add dsdp/tm/tcf_0_3_x
authorduane.cawthron@nokia.com
Mon, 17 Aug 2009 16:02:00 -0500
changeset 70 11a6943ebeb2
parent 69 b6b7ad8a25a3
child 71 51dbf4bbe3f7
add dsdp/tm/tcf_0_3_x
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.classpath
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.project
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.settings/org.eclipse.jdt.core.prefs
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.settings/org.eclipse.jdt.ui.prefs
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/META-INF/MANIFEST.MF
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/build.properties
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/ChannelLoop.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/ServiceManager.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/Token.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/TransportManager.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/ChannelProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/DiagnosticsService.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/GenericProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/StreamsProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractPeer.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/Base64.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ChannelTCP.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/Command.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ErrorReport.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ServerTCP.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/StreamChannel.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IErrorReport.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IEventQueue.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/ILogger.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IPeer.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IService.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IServiceProvider.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IToken.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/ITransportProvider.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/Protocol.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IBreakpoints.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IDiagnostics.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IExpressions.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IFileSystem.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILineNumbers.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IProcesses.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRegisters.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IStackTrace.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IStreams.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISysMonitor.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFFileInputStream.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFFileOutputStream.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFTask.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/.project
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Agent Porting Guide.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Architecture.png
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Context Identifier Explanation.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Getting Started.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Linux Agent Prototype.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Project.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Breakpoints.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - File System.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Memory.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Processes.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Registers.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Run Control.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Stack Trace.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Streams.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - System Monitor.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Services.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Specification Image1.png
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Specification.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_Launch_Dialog.jpg
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_RSE_Files.jpg
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_RSE_Processes.jpg
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/index.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.classpath
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.cvsignore
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.project
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.settings/org.eclipse.jdt.core.prefs
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.settings/org.eclipse.jdt.ui.prefs
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/META-INF/MANIFEST.MF
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/about.html
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/build.properties
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/plugin.properties
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/plugin.xml
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/schema/serviceProviders.exsd
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/schema/startup.exsd
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties
dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/ssl/TCFSecurityManager.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.classpath	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.project	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.tm.tcf.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.settings/org.eclipse.jdt.core.prefs	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,279 @@
+#Mon Jun 22 11:36:07 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/.settings/org.eclipse.jdt.ui.prefs	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,4 @@
+#Thu May 21 14:51:03 PDT 2009
+eclipse.preferences.version=1
+formatter_profile=_Java STD
+formatter_settings_version=11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/META-INF/MANIFEST.MF	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: TCF Core Fragment
+Bundle-SymbolicName: org.eclipse.tm.tcf.core;singleton:=true
+Bundle-Version: 0.2.0.qualifier
+Fragment-Host: org.eclipse.tm.tcf;bundle-version="0.2.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.tm.tcf.core;version="0.2.0",
+ org.eclipse.tm.tcf.protocol;version="0.2.0",
+ org.eclipse.tm.tcf.services;version="0.2.0",
+ org.eclipse.tm.tcf.util;version="0.2.0"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/build.properties	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/ChannelLoop.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import org.eclipse.tm.tcf.core.StreamChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+
+public class ChannelLoop extends StreamChannel {
+
+    private final byte[] buf = new byte[0x1000];
+    private int buf_inp;
+    private int buf_out;
+    private boolean waiting;
+    private boolean closed;
+
+    ChannelLoop(IPeer peer) {
+        super(peer);
+        start();
+    }
+
+    @Override
+    protected synchronized int get() throws IOException {
+        try {
+            while (buf_inp == buf_out) {
+                if (closed) return -1;
+                waiting = true;
+                wait();
+            }
+            int b = buf[buf_out] & 0xff;
+            buf_out = (buf_out + 1) % buf.length;
+            if (waiting) {
+                waiting = false;
+                notifyAll();
+            }
+            return b;
+        }
+        catch (InterruptedException e) {
+            throw new InterruptedIOException();
+        }
+    }
+
+    @Override
+    protected synchronized void put(int b) throws IOException {
+        assert b >=0  && b <= 0xff;
+        try {
+            for (;;) {
+                int nxt_inp = (buf_inp + 1) % buf.length;
+                if (nxt_inp != buf_out) {
+                    buf[buf_inp] = (byte)b;
+                    buf_inp = nxt_inp;
+                    break;
+                }
+                if (closed) return;
+                waiting = true;
+                wait();
+            }
+            if (waiting) {
+                waiting = false;
+                notifyAll();
+            }
+        }
+        catch (InterruptedException e) {
+            throw new InterruptedIOException();
+        }
+    }
+
+    @Override
+    protected void flush() throws IOException {
+    }
+
+    @Override
+    protected synchronized void stop() throws IOException {
+        closed = true;
+        if (waiting) {
+            waiting = false;
+            notifyAll();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.AbstractPeer;
+
+public class LocalPeer extends AbstractPeer {
+    
+    private static Map<String,String> createAttributes() {
+        Map<String, String> attrs = new HashMap<String, String>();
+        attrs.put(ATTR_ID, "TCFLocal");
+        attrs.put(ATTR_NAME, "Local Peer");
+        attrs.put(ATTR_OS_NAME, System.getProperty("os.name"));
+        attrs.put(ATTR_TRANSPORT_NAME, "Loop");
+        return attrs;
+    }
+
+    public LocalPeer() {
+        super(createAttributes());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.AbstractPeer;
+
+public class RemotePeer extends AbstractPeer {
+    
+    private long last_update_time;
+    
+    public RemotePeer(Map<String,String> attrs) {
+        super(attrs);
+        last_update_time = System.currentTimeMillis();
+    }
+    
+    @Override
+    public void updateAttributes(Map<String,String> attrs) {
+        super.updateAttributes(attrs);
+        last_update_time = System.currentTimeMillis();
+    }
+    
+    public long getLastUpdateTime() {
+        return last_update_time;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/ServiceManager.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Anyware Technologies and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Anyware Technologies  - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.services.local.DiagnosticsService;
+import org.eclipse.tm.internal.tcf.services.remote.GenericProxy;
+import org.eclipse.tm.internal.tcf.services.remote.LocatorProxy;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IServiceProvider;
+
+public class ServiceManager {
+
+    private static final Collection<IServiceProvider> providers = new ArrayList<IServiceProvider>();
+
+    static {
+        addServiceProvider(new IServiceProvider() {
+            
+            private final String package_name = LocatorProxy.class.getPackage().getName();
+            
+            public IService[] getLocalService(IChannel channel) {
+                return new IService[]{ new DiagnosticsService(channel) };
+            }
+
+            public IService getServiceProxy(IChannel channel, String service_name) {
+                IService service = null;
+                try {
+                    Class<?> cls = Class.forName(package_name + "." + service_name + "Proxy");
+                    service = (IService)cls.getConstructor(IChannel.class).newInstance(channel);
+                    assert service_name.equals(service.getName());
+                }
+                catch (Exception x) {
+                }
+                return service;
+            }
+        });
+
+    }
+
+    public static void addServiceProvider(IServiceProvider provider) {
+        providers.add(provider);
+    }
+
+    public static void removeServiceProvider(IServiceProvider provider) {
+        providers.remove(provider);
+    }
+    
+    public static void onChannelCreated(IChannel channel, Map<String,IService> services) {
+        IService zero_copy = new IService() {
+            public String getName() {
+                return "ZeroCopy";
+            }
+        };
+        services.put(zero_copy.getName(), zero_copy);
+        for (IServiceProvider provider : providers) {
+            IService[] arr = provider.getLocalService(channel);
+            if (arr == null) continue;
+            for (IService service : arr) {
+                if (services.containsKey(service.getName())) continue;
+                services.put(service.getName(), service);
+            }
+        }
+    }
+    
+    public static void onChannelOpened(IChannel channel, Collection<String> service_names, Map<String,IService> services) {
+        for (String name : service_names) {
+            for (IServiceProvider provider : providers) {
+                IService service = provider.getServiceProxy(channel, name);
+                if (service == null) continue;
+                services.put(name, service);
+                break;
+            }
+            if (!services.containsKey(name)) {
+                services.put(name, new GenericProxy(channel, name));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/Token.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+public class Token implements IToken {
+
+    private static int cnt = 0;
+
+    private final String id;
+    private final byte[] bytes;
+    private final IChannel.ICommandListener listener;
+
+    public Token() {
+        id = null;
+        bytes = null;
+        listener = null;
+    }
+
+    public Token(IChannel.ICommandListener listener) {
+        this.listener = listener;
+        id = Integer.toString(cnt++);
+        try {
+            bytes = id.getBytes("ASCII");
+        }
+        catch (UnsupportedEncodingException e) {
+            throw new Error(e);
+        }
+    }
+
+    public Token(byte[] bytes) {
+        this.bytes = bytes;
+        listener = null;
+        try {
+            id = new String(bytes, "ASCII");
+        }
+        catch (UnsupportedEncodingException e) {
+            throw new Error(e);
+        }
+    }
+
+    public boolean cancel() {
+        return false;
+    }
+
+    public String getID() {
+        return id;
+    }
+
+    public byte[] getBytes() {
+        return bytes;
+    }
+
+    public IChannel.ICommandListener getListener() {
+        return listener;
+    }
+    
+    @Override
+    public String toString() {
+        return id;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/core/TransportManager.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.tm.tcf.core.AbstractChannel;
+import org.eclipse.tm.tcf.core.AbstractPeer;
+import org.eclipse.tm.tcf.core.ChannelTCP;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.ITransportProvider;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+
+
+public class TransportManager {
+
+    private static final Collection<AbstractChannel> channels =
+        new LinkedList<AbstractChannel>();
+    private static final Collection<Protocol.ChannelOpenListener> listeners = 
+        new LinkedList<Protocol.ChannelOpenListener>();
+    private static final HashMap<String,ITransportProvider> transports =
+        new HashMap<String,ITransportProvider>();
+    
+    static {
+        addTransportProvider(new ITransportProvider() {
+
+            public String getName() {
+                return "TCP";
+            }
+
+            public IChannel openChannel(IPeer peer) {
+                assert getName().equals(peer.getTransportName());
+                Map<String,String> attrs = peer.getAttributes();
+                String host = attrs.get(IPeer.ATTR_IP_HOST);
+                String port = attrs.get(IPeer.ATTR_IP_PORT);
+                if (host == null) throw new Error("No host name");
+                if (port == null) throw new Error("No port number");
+                return new ChannelTCP(peer, host, Integer.parseInt(port), false);
+            }
+        });
+        
+        addTransportProvider(new ITransportProvider() {
+
+            public String getName() {
+                return "SSL";
+            }
+
+            public IChannel openChannel(IPeer peer) {
+                assert getName().equals(peer.getTransportName());
+                Map<String,String> attrs = peer.getAttributes();
+                String host = attrs.get(IPeer.ATTR_IP_HOST);
+                String port = attrs.get(IPeer.ATTR_IP_PORT);
+                if (host == null) throw new Error("No host name");
+                if (port == null) throw new Error("No port number");
+                return new ChannelTCP(peer, host, Integer.parseInt(port), true);
+            }
+        });
+        
+        addTransportProvider(new ITransportProvider() {
+
+            public String getName() {
+                return "Loop";
+            }
+
+            public IChannel openChannel(IPeer peer) {
+                assert getName().equals(peer.getTransportName());
+                return new ChannelLoop(peer);
+            }
+        });
+    }
+    
+    public static void addTransportProvider(ITransportProvider transport) {
+        String name = transport.getName();
+        assert name != null;
+        if (transports.get(name) != null) throw new Error("Already registered: " + name);
+        transports.put(name, transport);
+    }
+    
+    public static void removeTransportProvider(ITransportProvider transport) {
+        String name = transport.getName();
+        assert name != null;
+        if (transports.get(name) == transport) transports.remove(name);
+    }
+    
+    public static IChannel openChannel(IPeer peer) {
+        String name = peer.getTransportName();
+        if (name == null) throw new Error("No transport name");
+        ITransportProvider transport = transports.get(name);
+        if (transport == null) throw new Error("Unknown transport name: " + name);
+        return transport.openChannel(peer);
+    }
+
+    public static void channelOpened(final AbstractChannel channel) {
+        assert !channels.contains(channel);
+        channels.add(channel);
+        Protocol.ChannelOpenListener[] array = listeners.toArray(new Protocol.ChannelOpenListener[listeners.size()]);
+        for (Protocol.ChannelOpenListener l : array) {
+            try {
+                l.onChannelOpen(channel);
+            }
+            catch (Throwable x) {
+                Protocol.log("Exception in channel listener", x);
+            }
+        }
+    }
+
+    public static void channelClosed(final AbstractChannel channel, final Throwable x) {
+        assert channels.contains(channel);
+        channels.remove(channel);
+    }
+    
+    public static IChannel[] getOpenChannels() {
+        return channels.toArray(new IChannel[channels.size()]);
+    }
+    
+    public static void addChanelOpenListener(Protocol.ChannelOpenListener listener) {
+        assert listener != null;
+        listeners.add(listener);
+    }
+
+    public static void removeChanelOpenListener(Protocol.ChannelOpenListener listener) {
+        listeners.remove(listener);
+    }
+
+    public static void peerDisposed(AbstractPeer peer) {
+        Exception error = null;
+        Collection<AbstractChannel> bf = new ArrayList<AbstractChannel>(channels);
+        for (Iterator<AbstractChannel> i = bf.iterator(); i.hasNext();) {
+            AbstractChannel c = i.next();
+            if (c.getRemotePeer() != peer) continue;
+            if (error == null) error = new Exception("Peer is disposed");
+            c.terminate(error);
+        }
+    }
+
+    /**
+     * Transmit TCF event message.
+     * The message is sent to all open communication channels – broadcasted.
+     * 
+     * This is internal API, TCF clients should use {@code org.eclipse.tm.tcf.protocol.Protocol}.
+     */
+    public static void sendEvent(String service_name, String event_name, byte[] data) {
+        for (Iterator<AbstractChannel> i = channels.iterator(); i.hasNext();) {
+            AbstractChannel channel = i.next();
+            IService s = channel.getLocalService(service_name);
+            if (s != null) channel.sendEvent(s, event_name, data);
+        }
+    }
+    
+    /**
+     * Call back after TCF messages sent by this host up to this moment are delivered
+     * to their intended targets. This method is intended for synchronization of messages
+     * across multiple channels.
+     * 
+     * Note: Cross channel synchronization can reduce performance and throughput.
+     * Most clients don't need cross channel synchronization and should not call this method. 
+     *  
+     * @param done will be executed by dispatch thread after communication 
+     * messages are delivered to corresponding targets.
+     * 
+     * This is internal API, TCF clients should use {@code org.eclipse.tm.tcf.protocol.Protocol}.
+     */
+    public static void sync(final Runnable done) {
+        final Set<IToken> set = new HashSet<IToken>();
+        ILocator.DoneSync done_sync = new ILocator.DoneSync() {
+            public void doneSync(IToken token) {
+                assert set.contains(token);
+                set.remove(token);
+                if (set.isEmpty()) done.run();
+            }
+        };
+        for (Iterator<AbstractChannel> i = channels.iterator(); i.hasNext();) {
+            AbstractChannel channel = i.next();
+            ILocator s = channel.getRemoteService(ILocator.class);
+            if (s != null) set.add(s.sync(done_sync));
+        }
+        if (set.isEmpty()) Protocol.invokeLater(done);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/ChannelProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.local;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.core.ChannelLoop;
+import org.eclipse.tm.tcf.core.AbstractChannel;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+/**
+ * ChannelProxy implements forwarding of TCF messages between two channels.
+ * The class is used to implement Locator service "redirect" command.
+ */
+class ChannelProxy {
+
+    private final AbstractChannel ch_x;
+    private final AbstractChannel ch_y;
+    
+    private boolean closed_x;
+    private boolean closed_y;
+    
+    private final Map<IToken,IToken> tokens_x = new HashMap<IToken,IToken>();
+    private final Map<IToken,IToken> tokens_y = new HashMap<IToken,IToken>();
+    
+    private final AbstractChannel.Proxy proxy_x = new AbstractChannel.Proxy() {
+
+        public void onChannelClosed(Throwable error) {
+            closed_x = true;
+            if (closed_y) return;
+            if (error == null) ch_y.close();
+            else ch_y.terminate(error);
+        }
+
+        public void onCommand(IToken token, String service, String name, byte[] data) {
+            if (closed_y) return;
+            assert ch_y.getState() == IChannel.STATE_OPEN;
+            IService s = ch_y.getRemoteService(service);
+            if (s == null) ch_x.terminate(new IOException("Invalid service name"));
+            else tokens_x.put(ch_y.sendCommand(s, name, data, cmd_listener_x), token);
+        }
+        
+        public void onEvent(String service, String name, byte[] data) {
+            IService s = ch_x.getRemoteService(service);
+            if (s == null) ch_x.terminate(new IOException("Invalid service name"));
+            else if (!closed_y) ch_y.sendEvent(s, name, data);
+        }
+    };
+    
+    private final AbstractChannel.Proxy proxy_y = new AbstractChannel.Proxy() {
+
+        public void onChannelClosed(Throwable error) {
+            closed_y = true;
+            if (closed_x) return;
+            if (error == null) ch_x.close();
+            else ch_x.terminate(error);
+        }
+
+        public void onCommand(IToken token, String service, String name, byte[] data) {
+            if (closed_x) return;
+            assert ch_x.getState() == IChannel.STATE_OPEN;
+            IService s = ch_x.getRemoteService(service);
+            if (s == null) ch_y.terminate(new IOException("Invalid service name"));
+            else tokens_y.put(ch_x.sendCommand(s, name, data, cmd_listener_y), token);
+        }
+        
+        public void onEvent(String service, String name, byte[] data) {
+            IService s = ch_y.getRemoteService(service);
+            if (s == null) ch_y.terminate(new IOException("Invalid service name"));
+            else if (!closed_x) ch_x.sendEvent(s, name, data);
+        }
+    };
+    
+    private final IChannel.ICommandListener cmd_listener_x = new IChannel.ICommandListener() {
+
+        public void progress(IToken token, byte[] data) {
+            ch_x.sendProgress(tokens_x.get(token), data);
+        }
+
+        public void result(IToken token, byte[] data) {
+            ch_x.sendResult(tokens_x.get(token), data);
+            tokens_x.remove(token);
+        }
+
+        public void terminated(IToken token, Exception error) {
+            tokens_x.remove(token);
+        }
+    };
+    
+    private final IChannel.ICommandListener cmd_listener_y = new IChannel.ICommandListener() {
+
+        public void progress(IToken token, byte[] data) {
+            ch_y.sendProgress(tokens_y.get(token), data);
+        }
+
+        public void result(IToken token, byte[] data) {
+            ch_y.sendResult(tokens_y.get(token), data);
+            tokens_y.remove(token);
+        }
+
+        public void terminated(IToken token, Exception error) {
+            tokens_y.remove(token);
+        }
+    };
+    
+    ChannelProxy(IChannel x, IChannel y) {
+        assert !(x instanceof ChannelLoop);
+        assert !(y instanceof ChannelLoop);
+        ch_x = (AbstractChannel)x;
+        ch_y = (AbstractChannel)y;
+        assert ch_x.getState() == IChannel.STATE_OPEN;
+        assert ch_y.getState() == IChannel.STATE_OPENNING;
+        try {
+            ch_y.setProxy(proxy_y, ch_x.getRemoteServices());
+            ch_y.addChannelListener(new IChannel.IChannelListener() {
+
+                public void congestionLevel(int level) {
+                }
+
+                public void onChannelClosed(Throwable error) {
+                    ch_y.removeChannelListener(this);
+                    if (error == null) error = new Exception("Channel closed");
+                }
+
+                public void onChannelOpened() {
+                    ch_y.removeChannelListener(this);
+                    try {
+                        ch_x.setProxy(proxy_x, ch_y.getRemoteServices());
+                    }
+                    catch (IOException e) {
+                        ch_x.terminate(e);
+                        ch_y.terminate(e);
+                    }
+                }
+            });
+        }
+        catch (IOException e) {
+            ch_x.terminate(e);
+            ch_y.terminate(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/DiagnosticsService.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.local;
+
+import java.math.BigDecimal;
+
+import org.eclipse.tm.internal.tcf.core.Token;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IDiagnostics;
+
+
+public class DiagnosticsService implements IDiagnostics {
+
+    private final IChannel channel;
+    
+    private class CommandServer implements IChannel.ICommandServer {
+        
+        public void command(IToken token, String name, byte[] data) {
+            try {
+                command(token, name, JSON.parseSequence(data));
+            }
+            catch (Throwable x) {
+                channel.terminate(x);
+            }
+        }
+        
+        private void command(IToken token, String name, Object[] args) throws Exception {
+            if (name.equals("echo")) {
+                if (args.length != 1) throw new Exception("Invalid number of arguments");
+                String s = (String)args[0];
+                channel.sendResult(token, JSON.toJSONSequence(new Object[]{ s }));
+            }
+            else if (name.equals("echoFP")) {
+                if (args.length != 1) throw new Exception("Invalid number of arguments");
+                Number n = (Number)args[0];
+                channel.sendResult(token, JSON.toJSONSequence(new Object[]{ n }));
+            }
+            else if (name.equals("getTestList")) {
+                if (args.length != 0) throw new Exception("Invalid number of arguments");
+                channel.sendResult(token, JSON.toJSONSequence(new Object[]{ null, new String[0] }));
+            }
+            else {
+                channel.rejectCommand(token);
+            }
+        }
+    }
+
+    public DiagnosticsService(IChannel channel) {
+        this.channel = channel;
+        channel.addCommandServer(this, new CommandServer());
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken echo(final String s, final DoneEcho done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneEcho(token, null, s);
+            }
+        });
+        return token;
+    }
+
+    public IToken echoFP(final BigDecimal n, final DoneEchoFP done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneEchoFP(token, null, n);
+            }
+        });
+        return token;
+    }
+
+    public IToken getTestList(final DoneGetTestList done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneGetTestList(token, null, new String[0]);
+            }
+        });
+        return token;
+    }
+
+    public IToken runTest(final String s, final DoneRunTest done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneRunTest(token, new Exception("Test suite not found: " + s), null);
+            }
+        });
+        return token;
+    }
+
+    public IToken cancelTest(String context_id, final DoneCancelTest done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneCancelTest(token, null);
+            }
+        });
+        return token;
+    }
+
+    public IToken getSymbol(String context_id, String symbol_name, final DoneGetSymbol done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneGetSymbol(token, new Exception("Invalid context"), null);
+            }
+        });
+        return token;
+    }
+
+    public IToken createTestStreams(int inp_buf_size, int out_buf_size, final DoneCreateTestStreams done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneCreateTestStreams(token, new Exception("Not implemented"), null, null);
+            }
+        });
+        return token;
+    }
+
+    public IToken disposeTestStream(String id, final DoneDisposeTestStream done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneDisposeTestStream(token, new Exception("Invalid context"));
+            }
+        });
+        return token;
+    }
+
+    public IToken not_implemented_command(final DoneNotImplementedCommand done) {
+        final IToken token = new Token();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                done.doneNotImplementedCommand(token, new Exception("Not implemented"));
+            }
+        });
+        return token;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.local;
+
+import java.lang.reflect.Method;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.core.LocalPeer;
+import org.eclipse.tm.internal.tcf.core.RemotePeer;
+import org.eclipse.tm.internal.tcf.core.ServiceManager;
+import org.eclipse.tm.internal.tcf.core.TransportManager;
+import org.eclipse.tm.tcf.core.AbstractChannel;
+import org.eclipse.tm.tcf.core.AbstractPeer;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IServiceProvider;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+
+
+/**
+ * Locator service uses transport layer to search
+ * for peers and to collect and maintain up-to-date
+ * data about peer’s attributes.
+ */
+// TODO: research usage of DNS-SD (DNS Service Discovery) to discover TCF peers
+public class LocatorService implements ILocator {
+    
+    private static final int DISCOVEY_PORT = 1534;
+    private static final int MAX_PACKET_SIZE = 9000 - 40 - 8;
+    private static final int PREF_PACKET_SIZE = 1500 - 40 - 8;
+
+    private static LocatorService locator;
+    private static final Map<String,IPeer> peers = new HashMap<String,IPeer>();
+    private static final ArrayList<LocatorListener> listeners = new ArrayList<LocatorListener>();
+    
+    private final HashSet<SubNet> subnets = new HashSet<SubNet>();
+    private final ArrayList<Slave> slaves = new ArrayList<Slave>();
+    private final byte[] inp_buf = new byte[MAX_PACKET_SIZE];
+    private final byte[] out_buf = new byte[MAX_PACKET_SIZE];
+    
+    private InetAddress loopback_addr;
+    
+    private static class SubNet {
+        final int prefix_length;
+        final InetAddress address;
+        final InetAddress broadcast;
+        
+        long last_slaves_req_time;
+        boolean send_all_ok;
+        
+        SubNet(int prefix_length, InetAddress address, InetAddress broadcast) {
+            this.prefix_length = prefix_length;
+            this.address = address;
+            this.broadcast = broadcast;
+        }
+        
+        boolean contains(InetAddress addr) {
+            if (addr == null) return false;
+            byte[] a1 = addr.getAddress();
+            byte[] a2 = broadcast.getAddress();
+            int i = 0;
+            while (i + 8 <= prefix_length) {
+                int n = i / 8;
+                if (a1[n] != a2[n]) return false;
+                i += 8;
+            }
+            while (i < prefix_length) {
+                int n = i / 8;
+                int m = 1 << (7 - i % 8);
+                if ((a1[n] & m) != (a2[n] & m)) return false;
+                i++;
+            }
+            return true;
+        }
+        
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof SubNet)) return false;
+            SubNet x = (SubNet)o;
+            return
+                prefix_length == x.prefix_length &&
+                broadcast.equals(x.broadcast) &&
+                address.equals(x.address);
+        }
+        
+        @Override
+        public int hashCode() {
+            return broadcast.hashCode();
+        }
+        
+        @Override
+        public String toString() {
+            return broadcast.getHostAddress() + "/" + prefix_length;
+        }
+    }
+    
+    private static class Slave {
+        final InetAddress address;
+        final int port;
+        
+        /* Time of last packet receiver from this slave */
+        long last_packet_time;          
+        
+        /* Time of last REQ_SLAVES packet received from this slave */
+        long last_req_slaves_time;
+        
+        Slave(InetAddress address, int port) {
+            this.address = address;
+            this.port = port;
+        }
+        
+        @Override
+        public String toString() {
+            return address.getHostAddress() + ":" + port;
+        }
+    }
+    
+    private static LocalPeer local_peer;
+    
+    private DatagramSocket socket;
+    private long last_master_packet_time;
+    
+    private Thread timer_thread = new Thread() {
+        public void run() {
+            while (true) {
+                try {
+                    sleep(DATA_RETENTION_PERIOD / 4);
+                    Protocol.invokeAndWait(new Runnable() {
+                        public void run() {
+                            refresh_timer();
+                        }
+                    });
+                }
+                catch (IllegalStateException x) {
+                    // TCF event dispatch is shut down
+                    return;
+                }
+                catch (Throwable x) {
+                    Protocol.log("Unhandled exception in TCF discovery listening thread", x);
+                }
+            }
+        }
+    };
+    
+    private Thread input_thread = new Thread() {
+        public void run() {
+            for (;;) {
+                DatagramSocket socket = LocatorService.this.socket;
+                try {
+                    final DatagramPacket p = new DatagramPacket(inp_buf, inp_buf.length);
+                    socket.receive(p);
+                    Protocol.invokeAndWait(new Runnable() {
+                        public void run() {
+                            handleDatagramPacket(p);
+                        }
+                    });
+                }
+                catch (IllegalStateException x) {
+                    // TCF event dispatch is shutdown
+                    return;
+                }
+                catch (Exception x) {
+                    if (socket != LocatorService.this.socket) continue;
+                    Protocol.log("Cannot read from datagram socket", x);
+                }
+            }
+        }
+    };
+    
+    static {
+        ServiceManager.addServiceProvider(new IServiceProvider() {
+            
+            public IService[] getLocalService(final IChannel channel) {
+                channel.addCommandServer(locator, new IChannel.ICommandServer() {
+                    public void command(IToken token, String name, byte[] data) {
+                        locator.command((AbstractChannel)channel, token, name, data);
+                    }
+                });
+                return new IService[]{ locator };
+            }
+
+            public IService getServiceProxy(IChannel channel, String service_name) {
+                return null;
+            }
+        });
+    }
+    
+    public LocatorService() {
+        locator = this;
+        try {
+            loopback_addr = InetAddress.getByName(null);
+            out_buf[0] = 'T';
+            out_buf[1] = 'C';
+            out_buf[2] = 'F';
+            out_buf[3] = CONF_VERSION;
+            out_buf[4] = 0;
+            out_buf[5] = 0;
+            out_buf[6] = 0;
+            out_buf[7] = 0;
+            try {
+                socket = new DatagramSocket(DISCOVEY_PORT);
+            }
+            catch (BindException x) {
+                socket = new DatagramSocket();
+            }
+            socket.setBroadcast(true);
+            input_thread.setName("TCF Locator Receiver");
+            timer_thread.setName("TCF Locator Timer");
+            input_thread.setDaemon(true);
+            timer_thread.setDaemon(true);
+            input_thread.start();
+            timer_thread.start();
+            listeners.add(new LocatorListener() {
+
+                public void peerAdded(IPeer peer) {
+                    sendPeerInfo(peer, null, 0);
+                }
+
+                public void peerChanged(IPeer peer) {
+                    sendPeerInfo(peer, null, 0);
+                }
+
+                public void peerHeartBeat(String id) {
+                }
+
+                public void peerRemoved(String id) {
+                }
+            });
+            refreshSubNetList();
+            sendPeersRequest(null, 0);
+            sendAll(null, 0, null, System.currentTimeMillis());
+        }
+        catch (Exception x) {
+            Protocol.log("Cannot open UDP socket for TCF discovery protocol", x);
+        }
+    }
+
+    public static LocalPeer getLocalPeer() {
+        return local_peer;
+    }
+    
+    public static LocatorListener[] getListeners() {
+        return listeners.toArray(new LocatorListener[listeners.size()]);
+    }
+
+    public static void addPeer(AbstractPeer peer) {
+        assert peers.get(peer.getID()) == null;
+        if (peer instanceof LocalPeer) local_peer = (LocalPeer)peer;
+        peers.put(peer.getID(), peer);
+        peer.sendPeerAddedEvent();
+    }
+
+    public static void removePeer(AbstractPeer peer) {
+        String id = peer.getID();
+        assert peers.get(id) == peer;
+        peers.remove(id);
+        peer.sendPeerRemovedEvent();
+    }
+
+    private Map<String,Object> makeErrorReport(int code, String msg) {
+        Map<String,Object> err = new HashMap<String,Object>();
+        err.put(IErrorReport.ERROR_TIME, new Long(System.currentTimeMillis()));
+        err.put(IErrorReport.ERROR_CODE, new Integer(code));
+        err.put(IErrorReport.ERROR_FORMAT, msg);
+        return err;
+    }
+
+    private void command(final AbstractChannel channel, final IToken token, String name, byte[] data) {
+        try {
+            if (name.equals("redirect")) {
+                String peer_id = (String)JSON.parseSequence(data)[0];
+                IPeer peer = peers.get(peer_id);
+                if (peer == null) {
+                    channel.sendResult(token, JSON.toJSONSequence(new Object[]{
+                            makeErrorReport(IErrorReport.TCF_ERROR_UNKNOWN_PEER, "Unknown peer ID") }));
+                    return;
+                }
+                channel.sendResult(token, JSON.toJSONSequence(new Object[]{ null }));
+                if (peer instanceof LocalPeer) {
+                    channel.sendEvent(Protocol.getLocator(), "Hello", JSON.toJSONSequence(
+                            new Object[]{ channel.getLocalServices() }));
+                    return;
+                }
+                new ChannelProxy(channel, peer.openChannel());
+            }
+            else if (name.equals("sync")) {
+                channel.sendResult(token, null);
+            }
+            else if (name.equals("getPeers")) {
+                int i = 0;
+                Object[] arr = new Object[peers.size()];
+                for (IPeer p : peers.values()) arr[i++] = p.getAttributes(); 
+                channel.sendResult(token, JSON.toJSONSequence(new Object[]{ null, arr }));
+            }
+            else {
+                channel.rejectCommand(token);
+            }
+        }
+        catch (Throwable x) {
+            channel.terminate(x);
+        }
+    }
+    
+    private void refresh_timer() {
+        long time = System.currentTimeMillis();
+        /* Cleanup slave table */
+        if (slaves.size() > 0) {
+            int i = 0;
+            while (i < slaves.size()) {
+                Slave s = slaves.get(i);
+                if (s.last_packet_time + DATA_RETENTION_PERIOD < time) {
+                    slaves.remove(i);
+                }
+                else {
+                    i++;
+                }
+            }
+        }
+        /* Cleanup peers table */
+        ArrayList<RemotePeer> stale_peers = null;
+        for (IPeer p : peers.values()) {
+            if (p instanceof RemotePeer) {
+                RemotePeer r = (RemotePeer)p;
+                if (r.getLastUpdateTime() + DATA_RETENTION_PERIOD < time) {
+                    if (stale_peers == null) stale_peers = new ArrayList<RemotePeer>();
+                    stale_peers.add(r);
+                }
+            }
+        }
+        if (stale_peers != null) {
+            IChannel[] open_channels = TransportManager.getOpenChannels();
+            HashSet<IPeer> connected_peers = new HashSet<IPeer>();
+            for (IChannel c : open_channels) connected_peers.add(c.getRemotePeer());
+            for (RemotePeer p : stale_peers) {
+                if (!connected_peers.contains(p)) p.dispose();
+            }
+        }
+        /* Try to become a master */
+        if (socket.getLocalPort() != DISCOVEY_PORT && last_master_packet_time + DATA_RETENTION_PERIOD / 2 <= time) {
+            DatagramSocket s0 = socket;
+            DatagramSocket s1 = null;
+            try {
+                s1 = new DatagramSocket(DISCOVEY_PORT);
+                s1.setBroadcast(true);
+                socket = s1;
+                s0.close();
+            }
+            catch (Throwable x) {
+            }
+        }
+        refreshSubNetList();
+        sendAll(null, 0, null, time);
+    }
+    
+    private Slave addSlave(InetAddress addr, int port, long timestamp) {
+        for (Slave s : slaves) {
+            if (s.port == port && s.address.equals(addr)) {
+                if (s.last_packet_time < timestamp) s.last_packet_time = timestamp;
+                return s;
+            }
+        }
+        long time = System.currentTimeMillis();
+        Slave s = new Slave(addr, port);
+        s.last_packet_time = timestamp;
+        slaves.add(s);
+        sendPeersRequest(addr, port);
+        sendAll(addr, port, s, time);
+        sendSlaveInfo(s, time);
+        return s;
+    }
+    
+    private void refreshSubNetList() {
+        HashSet<SubNet> set = new HashSet<SubNet>(); 
+        try {
+            for (Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements();) {
+                NetworkInterface f = e.nextElement();
+                /* TODO: Class InterfaceAddress does not exists in Java versions before 1.6.
+                 * Fix the code below when support for old Java versions is not needed any more.
+                 */
+                try {
+                    Method m0 = f.getClass().getMethod("getInterfaceAddresses");
+                    for (Object ia : (List<?>)m0.invoke(f)) {
+                        Method m1 = ia.getClass().getMethod("getNetworkPrefixLength");
+                        Method m2 = ia.getClass().getMethod("getAddress");
+                        Method m3 = ia.getClass().getMethod("getBroadcast");
+                        int network_prefix_len = (Short)m1.invoke(ia);
+                        InetAddress address = (InetAddress)m2.invoke(ia);
+                        InetAddress broadcast = (InetAddress)m3.invoke(ia);
+                        if (broadcast == null) broadcast = address;
+                        set.add(new SubNet(network_prefix_len, address, broadcast));
+                    }
+                }
+                catch (Exception x) {
+                    // Java 1.5 or older
+                    // TODO: need a better way to get broadcast addresses on Java 1.5 VM 
+                    Enumeration<InetAddress> n = f.getInetAddresses();
+                    while (n.hasMoreElements()) {
+                        InetAddress addr = n.nextElement();
+                        byte[] buf = addr.getAddress();
+                        if (buf.length != 4) continue;
+                        buf[3] = (byte)255;
+                        try {
+                            set.add(new SubNet(24, addr, InetAddress.getByAddress(buf)));
+                        }
+                        catch (UnknownHostException y) {
+                        }
+                    }
+                }
+            }
+        }
+        catch (SocketException x) {
+            Protocol.log("Cannot get list of network interfaces", x);
+        }
+        for (Iterator<SubNet> i = subnets.iterator(); i.hasNext();) {
+            SubNet s = i.next();
+            if (set.contains(s)) continue;
+            i.remove();
+        }
+        for (Iterator<SubNet> i = set.iterator(); i.hasNext();) {
+            SubNet s = i.next();
+            if (subnets.contains(s)) continue;
+            subnets.add(s);
+        }
+    }
+    
+    private void sendPeersRequest(InetAddress addr, int port) {
+        out_buf[4] = CONF_REQ_INFO;
+        for (SubNet n : subnets) {
+            try {
+                if (addr == null) {
+                    socket.send(new DatagramPacket(out_buf, 8, n.broadcast, DISCOVEY_PORT));
+                    for (Slave slave : slaves) {
+                        if (!n.contains(slave.address)) continue;
+                        socket.send(new DatagramPacket(out_buf, 8, slave.address, slave.port));
+                    }
+                }
+                else if (n.contains(addr)) {
+                    socket.send(new DatagramPacket(out_buf, 8, addr, port));
+                }
+            }
+            catch (Exception x) {
+                Protocol.log("Cannot send datagram packet", x);
+            }
+        }
+    }
+    
+    private void sendPeerInfo(IPeer peer, InetAddress addr, int port) {
+        Map<String,String> attrs = peer.getAttributes();
+        if (attrs.get(IPeer.ATTR_IP_HOST) == null) return;
+        if (attrs.get(IPeer.ATTR_IP_PORT) == null) return;
+        try {
+            out_buf[4] = CONF_PEER_INFO;
+            int i = 8;
+            for (String key : attrs.keySet()) {
+                String s = key + "=" + attrs.get(key);
+                byte[] bt = s.getBytes("UTF-8");
+                if (i + bt.length >= out_buf.length) break; 
+                System.arraycopy(bt, 0, out_buf, i, bt.length);
+                i += bt.length;
+                out_buf[i++] = 0;
+            }
+            
+            InetAddress peer_addr = InetAddress.getByName(attrs.get(IPeer.ATTR_IP_HOST));
+            for (SubNet subnet : subnets) {
+                if (peer instanceof RemotePeer) {
+                    if (socket.getLocalPort() != DISCOVEY_PORT) return;
+                    if (!subnet.address.equals(loopback_addr) && !subnet.address.equals(peer_addr)) continue;
+                }
+                if (!subnet.address.equals(loopback_addr)) {
+                    if (!subnet.contains(peer_addr)) continue;
+                }
+                if (addr == null) {
+                    socket.send(new DatagramPacket(out_buf, i, subnet.broadcast, DISCOVEY_PORT));
+                    for (Slave slave : slaves) {
+                        if (!subnet.contains(slave.address)) continue;
+                        socket.send(new DatagramPacket(out_buf, i, slave.address, slave.port));
+                    }
+                    subnet.send_all_ok = true;
+                }
+                else if (subnet.contains(addr)) {
+                    socket.send(new DatagramPacket(out_buf, i, addr, port));
+                    subnet.send_all_ok = true;
+                }
+            }
+        }
+        catch (Exception x) {
+            Protocol.log("Cannot send datagram packet", x);
+        }
+    }
+    
+    private void sendEmptyPacket(InetAddress addr, int port) {
+        out_buf[4] = CONF_SLAVES_INFO;
+        for (SubNet n : subnets) {
+            if (n.send_all_ok) continue;
+            try {
+                if (addr == null) {
+                    socket.send(new DatagramPacket(out_buf, 8, n.broadcast, DISCOVEY_PORT));
+                    for (Slave slave : slaves) {
+                        if (!n.contains(slave.address)) continue;
+                        socket.send(new DatagramPacket(out_buf, 8, slave.address, slave.port));
+                    }
+                }
+                else if (n.contains(addr)) {
+                    socket.send(new DatagramPacket(out_buf, 8, addr, port));
+                }
+            }
+            catch (Exception x) {
+                Protocol.log("Cannot send datagram packet", x);
+            }
+        }
+    }
+    
+    private void sendAll(InetAddress addr, int port, Slave sl, long time) {
+        for (SubNet n : subnets) n.send_all_ok = false;
+        for (IPeer peer : peers.values()) sendPeerInfo(peer, addr, port);
+        if (addr != null && sl != null && sl.last_req_slaves_time + DATA_RETENTION_PERIOD >= time) {
+            sendSlavesInfo(addr, port, time);
+        }
+        sendEmptyPacket(addr, port);
+    }
+    
+    private void sendSlavesRequest(InetAddress addr, int port) {
+        try {
+            out_buf[4] = CONF_REQ_SLAVES;
+            socket.send(new DatagramPacket(out_buf, 8, addr, port));
+        }
+        catch (Exception x) {
+            Protocol.log("Cannot send datagram packet", x);
+        }
+    }
+    
+    private void sendSlaveInfo(Slave x, long time) {
+        out_buf[4] = CONF_SLAVES_INFO;
+        for (SubNet n : subnets) {
+            if (!n.contains(x.address)) continue;
+            try {
+                int i = 8;
+                String s = x.last_packet_time + ":" + x.port + ":" + x.address.getHostAddress();
+                byte[] bt = s.getBytes("UTF-8");
+                System.arraycopy(bt, 0, out_buf, i, bt.length);
+                i += bt.length;
+                out_buf[i++] = 0;
+                for (Slave y : slaves) {
+                if (!n.contains(y.address)) continue;
+                    if (y.last_req_slaves_time + DATA_RETENTION_PERIOD < time) continue;
+                    socket.send(new DatagramPacket(out_buf, i, y.address, y.port));
+                }
+            }
+            catch (Exception z) {
+                Protocol.log("Cannot send datagram packet", z);
+            }
+        }
+    }
+    
+    private void sendSlavesInfo(InetAddress addr, int port, long time) {
+        out_buf[4] = CONF_SLAVES_INFO;
+        for (SubNet n : subnets) {
+            if (!n.contains(addr)) continue;
+            try {
+                int i = 8;
+                for (Slave x : slaves) {
+                    if (x.last_packet_time + DATA_RETENTION_PERIOD < time) continue;
+                    if (x.port == port && x.address.equals(addr)) continue;
+                    if (!n.address.equals(loopback_addr)) {
+                        if (!n.contains(x.address)) continue;
+                    }
+                    n.send_all_ok = true;
+                    String s = x.last_packet_time + ":" + x.port + ":" + x.address.getHostAddress();
+                    byte[] bt = s.getBytes("UTF-8");
+                    if (i > 8 && i + bt.length >= PREF_PACKET_SIZE) {
+                        socket.send(new DatagramPacket(out_buf, i, addr, port));
+                        i = 8;
+                    }
+                    System.arraycopy(bt, 0, out_buf, i, bt.length);
+                    i += bt.length;
+                    out_buf[i++] = 0;
+                }
+                if (i > 8) socket.send(new DatagramPacket(out_buf, i, addr, port));
+            }
+            catch (Exception x) {
+                Protocol.log("Cannot send datagram packet", x);
+            }
+        }
+    }
+    
+    private boolean isRemote(InetAddress address, int port) {
+        if (port != socket.getLocalPort()) return true;
+        for (SubNet s : subnets) {
+            if (s.address.equals(address)) return false;
+        }
+        return true;
+    }
+    
+    private void handleDatagramPacket(DatagramPacket p) {
+        try {
+            long time = System.currentTimeMillis();
+            byte[] buf = p.getData();
+            int len = p.getLength();
+            if (len < 8) return;
+            if (buf[0] != 'T') return;
+            if (buf[1] != 'C') return;
+            if (buf[2] != 'F') return;
+            if (buf[3] != CONF_VERSION) return;
+            int remote_port = p.getPort();
+            InetAddress remote_address = p.getAddress(); 
+            if (isRemote(remote_address, remote_port)) {
+                Slave sl = null;
+                if (p.getPort() != DISCOVEY_PORT) {
+                    sl = addSlave(remote_address, remote_port, time);
+                }
+                switch (buf[4]) {
+                case CONF_PEER_INFO:
+                    handlePeerInfoPacket(p);
+                    break;
+                case CONF_REQ_INFO:
+                    handleReqInfoPacket(p, sl, time);
+                    break;
+                case CONF_SLAVES_INFO:
+                    handleSlavesInfoPacket(p);
+                    break;
+                case CONF_REQ_SLAVES:
+                    handleReqSlavesPacket(p, sl, time);
+                    break;
+                }
+                for (SubNet s : subnets) {
+                    if (!s.contains(remote_address)) continue;
+                    long delay = DATA_RETENTION_PERIOD / 3;
+                    if (remote_port != DISCOVEY_PORT) delay = DATA_RETENTION_PERIOD / 3 * 2;
+                    else if (!s.address.equals(remote_address)) delay = DATA_RETENTION_PERIOD / 2;
+                    if (s.last_slaves_req_time + delay <= time) {
+                        sendSlavesRequest(remote_address, remote_port);
+                        s.last_slaves_req_time = time;
+                    }
+                    if (s.address.equals(remote_address) && remote_port == DISCOVEY_PORT) {
+                        last_master_packet_time = time;
+                    }
+                }
+            }
+        }
+        catch (Throwable x) {
+            Protocol.log("Invalid datagram packet received", x);
+        }
+    }
+    
+    private void handlePeerInfoPacket(DatagramPacket p) {
+        try {
+            Map<String,String> map = new HashMap<String,String>();
+            String s = new String(p.getData(), 8, p.getLength() - 8, "UTF-8");
+            int l = s.length();
+            int i = 0;
+            while (i < l) {
+                int i0 = i;
+                while (i < l && s.charAt(i) != '=' && s.charAt(i) != 0) i++;
+                int i1 = i;
+                if (i < l && s.charAt(i) == '=') i++;
+                int i2 = i;
+                while (i < l && s.charAt(i) != 0) i++;
+                int i3 = i;
+                if (i < l && s.charAt(i) == 0) i++;
+                String key = s.substring(i0, i1);
+                String val = s.substring(i2, i3);
+                map.put(key, val);
+            }
+            String id = map.get(IPeer.ATTR_ID);
+            if (id == null) throw new Exception("Invalid peer info: no ID");
+            String peer_host = map.get(IPeer.ATTR_IP_HOST);
+            if (peer_host == null) return;
+            InetAddress peer_addr = InetAddress.getByName(peer_host);
+            for (SubNet subnet : subnets) {
+                if (!subnet.contains(peer_addr)) continue;
+                IPeer peer = peers.get(id);
+                if (peer instanceof RemotePeer) {
+                    ((RemotePeer)peer).updateAttributes(map);
+                }
+                else if (peer == null) {
+                    new RemotePeer(map);
+                }
+                break;
+            }
+        }
+        catch (Exception x) {
+            Protocol.log("Invalid datagram packet received", x);
+        }
+    }
+
+    private void handleReqInfoPacket(DatagramPacket p, Slave sl, long time) {
+        sendAll(p.getAddress(), p.getPort(), sl, time);
+    }
+
+    private void handleSlavesInfoPacket(DatagramPacket p) {
+        try {
+            String s = new String(p.getData(), 8, p.getLength() - 8, "UTF-8");
+            int l = s.length();
+            int i = 0;
+            while (i < l) {
+                int time0 = i;
+                while (i < l&& s.charAt(i) != ':' && s.charAt(i) != 0) i++;
+                int time1 = i;
+                if (i < l && s.charAt(i) == ':') i++;
+                int port0 = i;
+                while (i < l&& s.charAt(i) != ':' && s.charAt(i) != 0) i++;
+                int port1 = i;
+                if (i < l && s.charAt(i) == ':') i++;
+                int host0 = i;
+                while (i < l && s.charAt(i) != 0) i++;
+                int host1 = i;
+                if (i < l && s.charAt(i) == 0) i++;
+                int port = Integer.parseInt(s.substring(port0, port1));
+                if (port != DISCOVEY_PORT) {
+                    String host = s.substring(host0, host1);
+                    long time = time0 != time1 ? Long.parseLong(s.substring(time0, time1)) : System.currentTimeMillis();
+                    addSlave(InetAddress.getByName(host), port, time);
+                }
+            }
+        }
+        catch (Exception x) {
+            Protocol.log("Invalid datagram packet received", x);
+        }
+    }
+    
+    private void handleReqSlavesPacket(DatagramPacket p, Slave sl, long time) {
+        if (sl != null) sl.last_req_slaves_time = time;
+        sendSlavesInfo(p.getAddress(), p.getPort(),  time);
+    }
+    
+    /*----------------------------------------------------------------------------------*/
+
+    public static LocatorService getLocator() {
+        return locator;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+        
+    public Map<String,IPeer> getPeers() {
+        assert Protocol.isDispatchThread();
+        return peers;
+    }
+
+    public IToken redirect(String peer_id, DoneRedirect done) {
+        throw new Error("Channel redirect cannot be done on local peer");
+    }
+
+    public IToken sync(DoneSync done) {
+        throw new Error("Channel sync cannot be done on local peer");
+    }
+
+    public void addListener(LocatorListener listener) {
+        assert listener != null;
+        assert Protocol.isDispatchThread();
+        listeners.add(listener);
+    }
+
+    public void removeListener(LocatorListener listener) {
+        assert Protocol.isDispatchThread();
+        listeners.remove(listener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+
+
+public class BreakpointsProxy implements IBreakpoints {
+
+    private final IChannel channel;
+    private final Map<BreakpointsListener,IChannel.IEventListener> listeners =
+        new HashMap<BreakpointsListener,IChannel.IEventListener>();
+
+    public BreakpointsProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public IToken set(Map<String,Object>[] properties, final DoneCommand done) {
+        return new Command(channel, this, "set", new Object[]{ properties }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken add(Map<String,Object> properties, final DoneCommand done) {
+        return new Command(channel, this, "add", new Object[]{ properties }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken change(Map<String,Object> properties, final DoneCommand done) {
+        return new Command(channel, this, "change", new Object[]{ properties }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken disable(String[] ids, final DoneCommand done) {
+        return new Command(channel, this, "disable", new Object[]{ ids }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken enable(String[] ids, final DoneCommand done) {
+        return new Command(channel, this, "enable", new Object[]{ ids }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken remove(String[] ids, final DoneCommand done) {
+        return new Command(channel, this, "remove", new Object[]{ ids }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken getIDs(final DoneGetIDs done) {
+        return new Command(channel, this, "getIDs", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetIDs(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken getProperties(String id, final DoneGetProperties done) {
+        return new Command(channel, this, "getProperties", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Map<String,Object> map = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    map = (Map<String,Object>)args[1];
+                }
+                done.doneGetProperties(token, error, map);
+            }
+        }.token;
+    }
+
+    public IToken getStatus(String id, final DoneGetStatus done) {
+        return new Command(channel, this, "getStatus", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Map<String,Object> map = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    map = (Map<String,Object>)args[1];
+                }
+                done.doneGetStatus(token, error, map);
+            }
+        }.token;
+    }
+
+    public IToken getCapabilities(String id, final DoneGetCapabilities done) {
+        return new Command(channel, this, "getCapabilities", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Map<String,Object> map = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    map = (Map<String,Object>)args[1];
+                }
+                done.doneGetCapabilities(token, error, map);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String,Object>[] toBreakpointArray(Object o) {
+        if (o == null) return null;
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        return (Map<String,Object>[])c.toArray(new Map[c.size()]);
+    }
+
+    public void addListener(final BreakpointsListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            @SuppressWarnings("unchecked")
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("status")) {
+                        assert args.length == 2;
+                        listener.breakpointStatusChanged((String)args[0], (Map<String,Object>)args[1]);
+                    }
+                    else if (name.equals("contextAdded")) {
+                        assert args.length == 1;
+                        listener.contextAdded(toBreakpointArray(args[0]));
+                    }
+                    else if (name.equals("contextChanged")) {
+                        assert args.length == 1;
+                        listener.contextChanged(toBreakpointArray(args[0]));
+                    }
+                    else if (name.equals("contextRemoved")) {
+                        assert args.length == 1;
+                        listener.contextRemoved(toStringArray(args[0]));
+                    }
+                    else {
+                        throw new IOException("Breakpoints service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+
+    public void removeListener(BreakpointsListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IDiagnostics;
+
+
+public class DiagnosticsProxy implements IDiagnostics {
+    
+    private final IChannel channel;
+    
+    private static class Symbol implements ISymbol {
+        
+        private final Map<String,Object> props;
+        
+        Symbol(Map<String,Object> props) {
+            this.props = props;
+        }
+
+        public String getSectionName() {
+            return (String)props.get("Section");
+        }
+
+        public Number getValue() {
+            return (Number)props.get("Value");
+        }
+
+        public boolean isAbs() {
+            Boolean b = (Boolean)props.get("Abs");
+            return b != null && b.booleanValue();
+        }
+
+        public boolean isCommon() {
+            String s = (String)props.get("Storage");
+            return s != null && s.equals("COMMON");
+        }
+
+        public boolean isGlobal() {
+            String s = (String)props.get("Storage");
+            return s != null && s.equals("GLOBAL");
+        }
+
+        public boolean isLocal() {
+            String s = (String)props.get("Storage");
+            return s != null && s.equals("LOCAL");
+        }
+
+        public boolean isUndef() {
+            String s = (String)props.get("Storage");
+            return s != null && s.equals("UNDEF");
+        }
+    }
+    
+    public DiagnosticsProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken echo(String s, final DoneEcho done) {
+        return new Command(channel, this, "echo", new Object[]{ s }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String str = null;
+                if (error == null) {
+                    assert args.length == 1;
+                    str = (String)args[0];
+                }
+                done.doneEcho(token, error, str);
+            }
+        }.token;
+    }
+
+    public IToken echoFP(BigDecimal n, final DoneEchoFP done) {
+        return new Command(channel, this, "echoFP", new Object[]{ n }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                BigDecimal n = null;
+                if (error == null) {
+                    assert args.length == 1;
+                    Number x = (Number)args[0];
+                    if (x instanceof BigDecimal) {
+                        n = (BigDecimal)x;
+                    }
+                    else {
+                        n = new BigDecimal(x.toString());
+                    }
+                }
+                done.doneEchoFP(token, error, n);
+            }
+        }.token;
+    }
+
+    public IToken getTestList(final DoneGetTestList done) {
+        return new Command(channel, this, "getTestList", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetTestList(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken runTest(String s, final DoneRunTest done) {
+        return new Command(channel, this, "runTest", new Object[]{ s }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String str = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    str = (String)args[1];
+                }
+                done.doneRunTest(token, error, str);
+            }
+        }.token;
+    }
+
+    public IToken cancelTest(String s, final DoneCancelTest done) {
+        return new Command(channel, this, "cancelTest", new Object[]{ s }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCancelTest(token, error);
+            }
+        }.token;
+    }
+
+    public IToken getSymbol(String context_id, String symbol_name, final DoneGetSymbol done) {
+        return new Command(channel, this, "getSymbol", new Object[]{ context_id, symbol_name }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                ISymbol sym = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    sym = toSymbol(args[1]);
+                }
+                done.doneGetSymbol(token, error, sym);
+            }
+        }.token;
+    }
+
+    public IToken createTestStreams(int inp_buf_size, int out_buf_size, final DoneCreateTestStreams done) {
+        return new Command(channel, this, "createTestStreams", new Object[]{ inp_buf_size, out_buf_size }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String inp_id = null;
+                String out_id = null;
+                if (error == null) {
+                    assert args.length == 3;
+                    error = toError(args[0]);
+                    inp_id = (String)args[1];
+                    out_id = (String)args[2];
+                }
+                done.doneCreateTestStreams(token, error, inp_id, out_id);
+            }
+        }.token;
+    }
+
+    public IToken disposeTestStream(String id, final DoneDisposeTestStream done) {
+        return new Command(channel, this, "disposeTestStream", new Object[]{ id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneDisposeTestStream(token, error);
+            }
+        }.token;
+    }
+
+    public IToken not_implemented_command(final DoneNotImplementedCommand done) {
+        return new Command(channel, this, "not implemented command", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                done.doneNotImplementedCommand(token, error);
+            }
+        }.token;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private ISymbol toSymbol(Object o) {
+        if (o == null) return null;
+        return new Symbol((Map<String,Object>)o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IExpressions;
+import org.eclipse.tm.tcf.services.ISymbols.TypeClass;;
+
+public class ExpressionsProxy implements IExpressions {
+
+    private final IChannel channel;
+    private final Map<ExpressionsListener,IChannel.IEventListener> listeners =
+        new HashMap<ExpressionsListener,IChannel.IEventListener>();
+    
+    private class Context implements Expression {
+        
+        private final Map<String,Object> props;
+        
+        Context(Map<String,Object> props) {
+            this.props = props;
+        }
+
+        public boolean canAssign() {
+            Boolean n = (Boolean)props.get(PROP_CAN_ASSIGN);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public int getBits() {
+            Number n = (Number)props.get(PROP_BITS);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getExpression() {
+            return (String)props.get(PROP_EXPRESSION);
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getLanguage() {
+            return (String)props.get(PROP_LANGUAGE);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENT_ID);
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public int getSize() {
+            Number n = (Number)props.get(PROP_SIZE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getTypeID() {
+            return (String)props.get(PROP_TYPE);
+        }
+    }
+    
+    private class ContextValue implements Value {
+
+        private final byte[] value;
+        private final Map<String,Object> props;
+        
+        ContextValue(byte[] value, Map<String,Object> props) {
+            if (props == null) props = new HashMap<String,Object>();
+            this.value = value;
+            this.props = props;
+        }
+        
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public String getTypeID() {
+            return (String)props.get(VAL_TYPE);
+        }
+
+        public String getExeContextID() {
+            return (String)props.get(VAL_EXE_ID);
+        }
+
+        public byte[] getValue() {
+            return value;
+        }
+
+        public TypeClass getTypeClass() {
+            Number n = (Number)props.get(VAL_CLASS);
+            if (n != null) {
+                switch (n.intValue()) {
+                case 1: return TypeClass.cardinal;
+                case 2: return TypeClass.integer;
+                case 3: return TypeClass.real;
+                case 4: return TypeClass.pointer;
+                case 5: return TypeClass.array;
+                case 6: return TypeClass.composite;
+                case 7: return TypeClass.enumeration;
+                case 8: return TypeClass.function;
+                }
+            }
+            return TypeClass.unknown;
+        }
+
+        public boolean isBigEndian() {
+            Boolean n = (Boolean)props.get(VAL_BIG_ENDIAN);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+    }
+    
+    public ExpressionsProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public IToken assign(String id, byte[] value, final DoneAssign done) {
+        return new Command(channel, this, "assign", new Object[]{ id, new JSON.Binary(value, 0, value.length) }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneAssign(token, error);
+            }
+        }.token;
+    }
+
+    public IToken create(String parent_id, String language, String expression, final DoneCreate done) {
+        return new Command(channel, this, "create", new Object[]{ parent_id, language, expression }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Context ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]);
+                }
+                done.doneCreate(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken dispose(String id, final DoneDispose done) {
+        return new Command(channel, this, "dispose", new Object[]{ id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneDispose(token, error);
+            }
+        }.token;
+    }
+
+    public IToken evaluate(String id, final DoneEvaluate done) {
+        return new Command(channel, this, "evaluate", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                byte[] value = null;
+                Map<String,Object> props = null;
+                if (error == null) {
+                    assert args.length == 3;
+                    value = JSON.toByteArray(args[0]);
+                    error = toError(args[1]);
+                    props = (Map<String,Object>)args[2];
+                }
+                done.doneEvaluate(token, error, new ContextValue(value, props));
+            }
+        }.token;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] lst = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    lst = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, lst);
+            }
+        }.token;
+    }
+
+    public IToken getContext(String id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Context ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public void addListener(final ExpressionsListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("valueChanged")) {
+                        assert args.length == 1;
+                        listener.valueChanged((String)args[0]);
+                    }
+                    else {
+                        throw new IOException("Expressions service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+
+    public void removeListener(ExpressionsListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,595 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IFileSystem;
+
+
+public class FileSystemProxy implements IFileSystem {
+    
+    private final class FileHandle implements IFileHandle {
+        final String id;
+        
+        FileHandle(String id) {
+            this.id = id;
+        }
+
+        public IFileSystem getService() {
+            return FileSystemProxy.this;
+        }
+        
+        public String toString() {
+            return "[File Handle '" + id + "']";
+        }
+    }
+    
+    private static final class Status extends FileSystemException implements IErrorReport {
+        
+        private static final long serialVersionUID = -1636567076145085980L;
+        
+        private final int status;
+        private final Map<String,Object> attrs;
+        
+        Status(int status, String message, Map<String,Object> attrs) {
+            super(message);
+            this.status = status;
+            this.attrs = attrs;
+        }
+        
+        Status(Exception x) {
+            super(x);
+            this.status = IErrorReport.TCF_ERROR_OTHER;
+            this.attrs = new HashMap<String,Object>();
+        }
+        
+        public int getStatus() {
+            return status;
+        }
+
+        public int getErrorCode() {
+            Number n = (Number)attrs.get(ERROR_CODE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public int getAltCode() {
+            Number n = (Number)attrs.get(ERROR_ALT_CODE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getAltOrg() {
+            return (String)attrs.get(ERROR_ALT_ORG);
+        }
+
+        public Map<String, Object> getAttributes() {
+            return attrs;
+        }
+    }
+    
+    private abstract class FileSystemCommand extends Command {
+        
+        FileSystemCommand(String command, Object[] args) {
+            super(channel, FileSystemProxy.this, command, args);
+        }
+        
+        @SuppressWarnings("unchecked")
+        public Status toFSError(Object data) {
+            if (data == null) return null;
+            Map<String,Object> map = (Map<String,Object>)data;
+            Number error_code = (Number)map.get(IErrorReport.ERROR_CODE);
+            String cmd = getCommandString();
+            if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
+            Status s = new Status(error_code.intValue(),
+                    "TCF command exception:" +
+                    "\nCommand: " + cmd +
+                    "\nException: " + toErrorString(data) +
+                    "\nError code: " + error_code, map);
+            Object caused_by = map.get(IErrorReport.ERROR_CAUSED_BY);
+            if (caused_by != null) s.initCause(toError(caused_by, false));
+            return s;
+        }
+    }
+    
+    private final IChannel channel;
+    
+    public FileSystemProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public IToken close(IFileHandle handle, final DoneClose done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        return new FileSystemCommand("close", new Object[]{ id }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneClose(token, s);
+            }
+        }.token;
+    }
+
+    public IToken setstat(String path, FileAttrs attrs, final DoneSetStat done) {
+        Object dt = toObject(attrs);
+        return new FileSystemCommand("setstat", new Object[]{ path, dt }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneSetStat(token, s);
+            }
+        }.token;
+    }
+
+    public IToken fsetstat(IFileHandle handle, FileAttrs attrs, final DoneSetStat done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        Object dt = toObject(attrs);
+        return new FileSystemCommand("fsetstat", new Object[]{ id, dt }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneSetStat(token, s);
+            }
+        }.token;
+    }
+
+    public IToken stat(String path, final DoneStat done) {
+        return new FileSystemCommand("stat", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                FileAttrs a = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) a = toFileAttrs(args[1]);
+                }
+                done.doneStat(token, s, a);
+            }
+        }.token;
+    }
+
+    public IToken fstat(IFileHandle handle, final DoneStat done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        return new FileSystemCommand("fstat", new Object[]{ id }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                FileAttrs a = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) a = toFileAttrs(args[1]);
+                }
+                done.doneStat(token, s, a);
+            }
+        }.token;
+    }
+
+    public IToken lstat(String path, final DoneStat done) {
+        return new FileSystemCommand("lstat", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                FileAttrs a = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) a = toFileAttrs(args[1]);
+                }
+                done.doneStat(token, s, a);
+            }
+        }.token;
+    }
+
+    public IToken mkdir(String path, FileAttrs attrs, final DoneMkDir done) {
+        Object dt = toObject(attrs);
+        return new FileSystemCommand("mkdir", new Object[]{ path, dt }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneMkDir(token, s);
+            }
+        }.token;
+    }
+
+    public IToken open(String file_name, int flags, FileAttrs attrs, final DoneOpen done) {
+        Object dt = toObject(attrs);
+        return new FileSystemCommand("open", new Object[]{ file_name, new Integer(flags), dt }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                FileHandle h = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) h = toFileHandle(args[1]);
+                }
+                done.doneOpen(token, s, h);
+            }
+        }.token;
+    }
+
+    public IToken opendir(String path, final DoneOpen done) {
+        return new FileSystemCommand("opendir", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                FileHandle h = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) h = toFileHandle(args[1]);
+                }
+                done.doneOpen(token, s, h);
+            }
+        }.token;
+    }
+
+    public IToken read(IFileHandle handle, long offset, int len, final DoneRead done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        return new FileSystemCommand("read", new Object[]{
+                id, Long.valueOf(offset), Integer.valueOf(len) }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                byte[] b = null;
+                boolean eof = false;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 3;
+                    s = toFSError(args[1]);
+                    if (s == null) {
+                        b = JSON.toByteArray(args[0]);
+                        eof = ((Boolean)args[2]).booleanValue();
+                    }
+                }
+                done.doneRead(token, s, b, eof);
+            }
+        }.token;
+    }
+
+    public IToken readdir(IFileHandle handle, final DoneReadDir done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        return new FileSystemCommand("readdir", new Object[]{ id }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                DirEntry[] b = null;
+                boolean eof = false;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 3;
+                    s = toFSError(args[1]);
+                    if (s == null) {
+                        b = toDirEntryArray(args[0]);
+                        eof = ((Boolean)args[2]).booleanValue();
+                    }
+                }
+                done.doneReadDir(token, s, b, eof);
+            }
+        }.token;
+    }
+
+    public IToken roots(final DoneRoots done) {
+        return new FileSystemCommand("roots", null) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                DirEntry[] b = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[1]);
+                    if (s == null) b = toDirEntryArray(args[0]);
+                }
+                done.doneRoots(token, s, b);
+            }
+        }.token;
+    }
+
+    public IToken readlink(String path, final DoneReadLink done) {
+        return new FileSystemCommand("readlink", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                String p = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) p = (String)args[1];
+                }
+                done.doneReadLink(token, s, p);
+            }
+        }.token;
+    }
+
+    public IToken realpath(String path, final DoneRealPath done) {
+        return new FileSystemCommand("realpath", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                String p = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 2;
+                    s = toFSError(args[0]);
+                    if (s == null) p = (String)args[1];
+                }
+                done.doneRealPath(token, s, p);
+            }
+        }.token;
+    }
+
+    public IToken remove(String file_name, final DoneRemove done) {
+        return new FileSystemCommand("remove", new Object[]{ file_name }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneRemove(token, s);
+            }
+        }.token;
+    }
+
+    public IToken rename(String old_path, String new_path, final DoneRename done) {
+        return new FileSystemCommand("rename", new Object[]{ old_path, new_path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneRename(token, s);
+            }
+        }.token;
+    }
+
+    public IToken rmdir(String path, final DoneRemove done) {
+        return new FileSystemCommand("rmdir", new Object[]{ path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneRemove(token, s);
+            }
+        }.token;
+    }
+
+    public IToken symlink(String link_path, String target_path, final DoneSymLink done) {
+        return new FileSystemCommand("symlink", new Object[]{ link_path, target_path }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneSymLink(token, s);
+            }
+        }.token;
+    }
+
+    public IToken write(IFileHandle handle, long offset, byte[] data,
+            int data_pos, int data_size, final DoneWrite done) {
+        assert handle.getService() == this;
+        String id = ((FileHandle)handle).id;
+        return new FileSystemCommand("write", new Object[]{
+                id, Long.valueOf(offset), new JSON.Binary(data, data_pos, data_size) }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneWrite(token, s);
+            }
+        }.token;
+    }
+
+    public IToken copy(String src_path, String dst_path,
+            boolean copy_permissions, boolean copy_uidgid, final DoneCopy done) {
+        return new FileSystemCommand("copy", new Object[]{
+                src_path, dst_path, Boolean.valueOf(copy_permissions),
+                Boolean.valueOf(copy_uidgid) }) {
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 1;
+                    s = toFSError(args[0]);
+                }
+                done.doneCopy(token, s);
+            }
+        }.token;
+    }
+
+    public IToken user(final DoneUser done) {
+        return new FileSystemCommand("user", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                Status s = null;
+                int r_uid = 0;
+                int e_uid = 0;
+                int r_gid = 0;
+                int e_gid = 0;
+                String home = null;
+                if (error != null) {
+                    s = new Status(error);
+                }
+                else {
+                    assert args.length == 5;
+                    r_uid = ((Number)args[0]).intValue();
+                    e_uid = ((Number)args[1]).intValue();
+                    r_gid = ((Number)args[2]).intValue();
+                    e_gid = ((Number)args[3]).intValue();
+                    home = (String)args[4];
+                }
+                done.doneUser(token, s, r_uid, e_uid, r_gid, e_gid, home);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+    
+    private Object toObject(FileAttrs attrs) {
+        if (attrs == null) return null;
+        Map<String,Object> m = new HashMap<String,Object>();
+        if (attrs.attributes != null) m.putAll(attrs.attributes);
+        if ((attrs.flags & ATTR_SIZE) != 0) {
+            m.put("Size", Long.valueOf(attrs.size));
+        }
+        if ((attrs.flags & ATTR_UIDGID) != 0) {
+            m.put("UID", Integer.valueOf(attrs.uid));
+            m.put("GID", Integer.valueOf(attrs.gid));
+        }
+        if ((attrs.flags & ATTR_PERMISSIONS) != 0) {
+            m.put("Permissions", Integer.valueOf(attrs.permissions));
+        }
+        if ((attrs.flags & ATTR_ACMODTIME) != 0) {
+            m.put("ATime", Long.valueOf(attrs.atime));
+            m.put("MTime", Long.valueOf(attrs.mtime));
+        }
+        return m;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private FileAttrs toFileAttrs(Object o) {
+        if (o == null) return null;
+        Map<String,Object> m = new HashMap<String,Object>((Map<String,Object>)o);
+        int flags = 0;
+        long size = 0;
+        int uid = 0;
+        int gid = 0;
+        int permissions = 0;
+        long atime = 0;
+        long mtime = 0;
+        Number n = (Number)m.remove("Size");
+        if (n != null) {
+            size = n.longValue();
+            flags |= ATTR_SIZE;
+        }
+        Number n1 = (Number)m.remove("UID");
+        Number n2 = (Number)m.remove("GID");
+        if (n1 != null && n2 != null) {
+            uid = n1.intValue();
+            gid = n2.intValue();
+            flags |= ATTR_UIDGID;
+        }
+        n = (Number)m.remove("Permissions");
+        if (n != null) {
+            permissions = n.intValue();
+            flags |= ATTR_PERMISSIONS;
+        }
+        n1 = (Number)m.remove("ATime");
+        n2 = (Number)m.remove("MTime");
+        if (n1 != null && n2 != null) {
+            atime = n1.longValue();
+            mtime = n2.longValue();
+            flags |= ATTR_ACMODTIME;
+        }
+        return new FileAttrs(flags, size, uid, gid, permissions, atime, mtime, m);
+    }
+    
+    private FileHandle toFileHandle(Object o) {
+        if (o == null) return null;
+        return new FileHandle(o.toString());
+    }
+    
+    @SuppressWarnings("unchecked")
+    private DirEntry[] toDirEntryArray(Object o) {
+        if (o == null) return null;
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        DirEntry[] res = new DirEntry[c.size()];
+        int i = 0;
+        for (Map<String,Object> m : c) {
+            res[i++] = new DirEntry(
+                    (String)m.get("FileName"),
+                    (String)m.get("LongName"),
+                    toFileAttrs(m.get("Attrs")));
+        }
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/GenericProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IService;
+
+/**
+ * Objects of GenericProxy class represent remote services, which don't
+ * have a proxy class defined for them.
+ * Clients still can use such services, but framework will not provide
+ * service specific utility methods for message formatting and parsing.
+ */
+public class GenericProxy implements IService {
+
+    private final IChannel channel;
+    private final String name;
+
+    public GenericProxy(IChannel channel, String name) {
+        this.channel = channel;
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public IChannel getChannel() {
+        return channel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,80 @@
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.ILineNumbers;
+
+
+public class LineNumbersProxy implements ILineNumbers {
+    
+    private final IChannel channel;
+
+    public LineNumbersProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken mapToSource(String context_id, Number start_address,
+            Number end_address, final DoneMapToSource done) {
+        return new Command(channel, this, "mapToSource", new Object[]{ context_id,
+                start_address, end_address }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                CodeArea[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toTextAreaArray(args[1]);
+                }
+                done.doneMapToSource(token, error, arr);
+            }
+        }.token;
+    }
+    
+    private static int getInteger(Map<String,Object> map, String name, int def) {
+        Number n = (Number)map.get(name);
+        if (n == null) return def;
+        return n.intValue();
+    }
+    
+    private static String getString(Map<String,Object> map, String name, String def) {
+        String s = (String)map.get(name);
+        if (s == null) return def;
+        return s;
+    }
+    
+    private static boolean getBoolean(Map<String,Object> map, String name) {
+        Boolean b = (Boolean)map.get(name);
+        if (b == null) return false;
+        return b.booleanValue();
+    }
+    
+    @SuppressWarnings("unchecked")
+    private CodeArea[] toTextAreaArray(Object o) {
+        if (o == null) return null;
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        int n = 0;
+        CodeArea[] arr = new CodeArea[c.size()];
+        String directory = null;
+        String file = null;
+        for (Map<String,Object> area : c) {
+            directory = getString(area, "Dir", directory);
+            file = getString(area, "File", file);
+            arr[n++] = new CodeArea(directory, file,
+                    getInteger(area, "SLine", 0), getInteger(area, "SCol", 0),
+                    getInteger(area, "ELine", 0), getInteger(area, "ECol", 0),
+                    (Number)area.get("SAddr"), (Number)area.get("EAddr"),
+                    getInteger(area, "ISA", 0),
+                    getBoolean(area, "IsStmt"), getBoolean(area, "BasicBlock"),
+                    getBoolean(area, "PrologueEnd"), getBoolean(area, "EpilogueBegin"));
+        }
+        return arr;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+
+
+public class LocatorProxy implements ILocator {
+    
+    private final IChannel channel;
+    private final Map<String,IPeer> peers = new HashMap<String,IPeer>();
+    private final Collection<LocatorListener> listeners = new ArrayList<LocatorListener>();
+    
+    private boolean get_peers_done = false;
+    
+    private class Peer implements IPeer {
+        
+        private final IPeer parent;
+        
+        private final Map<String, String> attrs;
+        
+        Peer(IPeer parent, Map<String,String> attrs) {
+            this.parent = parent;
+            this.attrs = attrs;
+        }
+
+        public Map<String, String> getAttributes() {
+            assert Protocol.isDispatchThread();
+            return attrs;
+        }
+
+        public String getID() {
+            assert Protocol.isDispatchThread();
+            return attrs.get(ATTR_ID);
+        }
+
+        public String getName() {
+            assert Protocol.isDispatchThread();
+            return attrs.get(ATTR_NAME);
+        }
+
+        public String getOSName() {
+            assert Protocol.isDispatchThread();
+            return attrs.get(ATTR_OS_NAME);
+        }
+
+        public String getTransportName() {
+            assert Protocol.isDispatchThread();
+            return attrs.get(ATTR_TRANSPORT_NAME);
+        }
+
+        public IChannel openChannel() {
+            assert Protocol.isDispatchThread();
+            IChannel c = parent.openChannel();
+            c.redirect(getID());
+            return c;
+        }
+    };
+
+    private final IChannel.IEventListener event_listener = new IChannel.IEventListener() {
+
+        @SuppressWarnings("unchecked")
+        public void event(String name, byte[] data) {
+            try {
+                Object[] args = JSON.parseSequence(data);
+                if (name.equals("peerAdded")) {
+                    assert args.length == 1;
+                    IPeer peer = new Peer(channel.getRemotePeer(), (Map<String,String>)args[0]);
+                    if (peers.get(peer.getID()) != null) {
+                        Protocol.log("Invalid peerAdded event", new Error());
+                        return;
+                    }
+                    peers.put(peer.getID(), peer);
+                    for (LocatorListener l : listeners.toArray(new LocatorListener[listeners.size()])) {
+                        try {
+                            l.peerAdded(peer);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Unhandled exception in Locator listener", x);
+                        }
+                    }
+                }
+                else if (name.equals("peerChanged")) {
+                    assert args.length == 1;
+                    Map<String,String> m = (Map<String,String>)args[0];
+                    if (m == null) throw new Error("Locator service: invalid peerChanged event - no peer ID");
+                    IPeer peer = peers.get(m.get(IPeer.ATTR_ID));
+                    if (peer == null) return;
+                    peers.put(peer.getID(), peer);
+                    for (LocatorListener l : listeners.toArray(new LocatorListener[listeners.size()])) {
+                        try {
+                            l.peerChanged(peer);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Unhandled exception in Locator listener", x);
+                        }
+                    }
+                }
+                else if (name.equals("peerRemoved")) {
+                    assert args.length == 1;
+                    String id = (String)args[0];
+                    IPeer peer = peers.remove(id);
+                    if (peer == null) return;
+                    for (LocatorListener l : listeners.toArray(new LocatorListener[listeners.size()])) {
+                        try {
+                            l.peerRemoved(id);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Unhandled exception in Locator listener", x);
+                        }
+                    }
+                }
+                else if (name.equals("peerHeartBeat")) {
+                    assert args.length == 1;
+                    String id = (String)args[0];
+                    IPeer peer = peers.get(id);
+                    if (peer == null) return;
+                    for (LocatorListener l : listeners.toArray(new LocatorListener[listeners.size()])) {
+                        try {
+                            l.peerHeartBeat(id);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Unhandled exception in Locator listener", x);
+                        }
+                    }
+                }
+                else {
+                    throw new IOException("Locator service: unknown event: " + name);
+                }
+            }
+            catch (Throwable x) {
+                channel.terminate(x);
+            }
+        }
+    };
+    
+    public LocatorProxy(IChannel channel) {
+        this.channel = channel;
+        channel.addEventListener(this, event_listener);
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public Map<String,IPeer> getPeers() {
+        return peers;
+    }
+
+    public IToken redirect(String peer_id, final DoneRedirect done) {
+        return new Command(channel, this, "redirect", new Object[]{ peer_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneRedirect(token, error);
+            }
+        }.token;
+    }
+
+    public IToken sync(final DoneSync done) {
+        return new Command(channel, this, "sync", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error != null) channel.terminate(error);
+                done.doneSync(token);
+            }
+        }.token;
+    }
+
+    public void addListener(LocatorListener listener) {
+        listeners.add(listener);
+        if (!get_peers_done) {
+            new Command(channel, this, "getPeers", null) {
+                @SuppressWarnings("unchecked")
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 2;
+                        error = toError(args[0]);
+                    }
+                    if (error != null) {
+                        Protocol.log("Locator error", error);
+                        return;
+                    }
+                    Collection<?> c = (Collection<?>)args[1];
+                    if (c != null) {
+                        for (Object o : c) {
+                            Map<String,String> m = (Map<String,String>)o;
+                            String id = m.get(IPeer.ATTR_ID);
+                            if (peers.get(id) != null) continue;
+                            IPeer peer = new Peer(channel.getRemotePeer(), m);
+                            peers.put(id, peer);
+                            for (LocatorListener l : listeners.toArray(new LocatorListener[listeners.size()])) {
+                                try {
+                                    l.peerAdded(peer);
+                                }
+                                catch (Throwable x) {
+                                    Protocol.log("Unhandled exception in Locator listener", x);
+                                }
+                            }
+                        }
+                    }
+                }
+            };
+            get_peers_done = true;
+        }
+    }
+
+    public void removeListener(LocatorListener listener) {
+        listeners.remove(listener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,407 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IMemory;
+
+
+public class MemoryProxy implements IMemory {
+
+    private final IChannel channel;
+    private final Map<MemoryListener,IChannel.IEventListener> listeners =
+        new HashMap<MemoryListener,IChannel.IEventListener>();
+    
+    private static class Range implements Comparable<Range> {
+        int offs;
+        int size;
+        int stat;
+        String msg;
+        
+        public int compareTo(Range o) {
+            if (offs < o.offs) return -1;
+            if (offs > o.offs) return +1;
+            return 0;
+        }
+    }
+    
+    private class MemoryErrorReport extends MemoryError implements ErrorOffset, IErrorReport {
+        
+        private static final long serialVersionUID = 796525409870265390L;
+        private final Map<String,Object> attrs;
+        private final Range[] ranges;
+        
+        @SuppressWarnings("unchecked")
+        MemoryErrorReport(String msg, Map<String,Object> attrs, Number addr, Object ranges) {
+            super(msg);
+            this.attrs = attrs;
+            Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)ranges;
+            this.ranges = c == null ? null : new Range[c.size()];
+            if (c != null) {
+                int n = 0;
+                BigInteger addr_bi = addr instanceof BigInteger ?
+                        (BigInteger)addr : new BigInteger(addr.toString());
+                for (Map<String,Object> m : c) {
+                    Range r = new Range();
+                    Number x = (Number)m.get("addr");
+                    BigInteger y = x instanceof BigInteger ?
+                            (BigInteger)x : new BigInteger(x.toString());
+                    r.offs = addr_bi.subtract(y).intValue();
+                    r.size = ((Number)m.get("size")).intValue();
+                    r.stat = ((Number)m.get("stat")).intValue();
+                    r.msg = Command.toErrorString(m.get("msg"));
+                    assert r.offs >= 0;
+                    assert r.size >= 0;
+                    this.ranges[n++] = r;
+                }
+                Arrays.sort(this.ranges);
+            }
+        }
+
+        public int getErrorCode() {
+            Number n = (Number)attrs.get(ERROR_CODE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public int getAltCode() {
+            Number n = (Number)attrs.get(ERROR_ALT_CODE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getAltOrg() {
+            return (String)attrs.get(ERROR_ALT_ORG);
+        }
+
+        public Map<String, Object> getAttributes() {
+            return attrs;
+        }
+
+        public String getMessage(int offset) {
+            if (ranges == null) return null;
+            int l = 0;
+            int h = ranges.length - 1;
+            while (l <= h) {
+                int n = (l + h) / 2;
+                Range r = ranges[n];
+                if (r.offs > offset) {
+                    h = n - 1;
+                }
+                else if (offset >= r.offs + r.size) {
+                    l = n + 1;
+                }
+                else {
+                    return r.msg;
+                }
+            }
+            return null;
+        }
+
+        public int getStatus(int offset) {
+            if (ranges == null) return BYTE_UNKNOWN;
+            int l = 0;
+            int h = ranges.length - 1;
+            while (l <= h) {
+                int n = (l + h) / 2;
+                Range r = ranges[n];
+                if (r.offs > offset) {
+                    h = n - 1;
+                }
+                else if (offset >= r.offs + r.size) {
+                    l = n + 1;
+                }
+                else {
+                    return r.stat;
+                }
+            }
+            return BYTE_UNKNOWN;
+        }
+    }
+
+    private class MemContext implements MemoryContext {
+
+        private final Map<String,Object> props;
+
+        MemContext(Map<String,Object> props) {
+            this.props = props;
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENT_ID);
+        }
+
+        public int getAddressSize() {
+            Number n = (Number)props.get(PROP_ADDRESS_SIZE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getProcessID() {
+            return (String)props.get(PROP_PROCESS_ID);
+        }
+
+        public boolean isBigEndian() {
+            Boolean n = (Boolean)props.get(PROP_BIG_ENDIAN);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        @SuppressWarnings("unchecked")
+        public Collection<String> getAccessTypes() {
+            return (Collection<String>)props.get(PROP_ACCESS_TYPES);
+        }
+
+        public Number getEndBound() {
+            return (Number)props.get(PROP_END_BOUND);
+        }
+
+        public String getName() {
+            return (String)props.get(PROP_NAME);
+        }
+
+        public Number getStartBound() {
+            return (Number)props.get(PROP_START_BOUND);
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public IToken fill(final Number addr, int word_size,
+                byte[] value, int size, int mode, final DoneMemory done) {
+            return new MemoryCommand("fill", new Object[] {
+                getID(), addr, word_size, size, mode, value
+            } ) {
+                public void done(Exception error, Object[] args) {
+                    MemoryError e = null;
+                    if (error != null) {
+                        e = new MemoryError(error.getMessage());
+                    }
+                    else {
+                        assert args.length == 2;
+                        e = toMemoryError(addr, args[0], args[1]);
+                    }
+                    done.doneMemory(token, e);
+                }
+            }.token;
+        }
+
+        public IToken get(final Number addr, int word_size,
+                final byte[] buf, final int offs, final int size,
+                int mode, final DoneMemory done) {
+            return new MemoryCommand("get", new Object[] {
+                    getID(), addr, word_size, size, mode
+                } ) {
+                    public void done(Exception error, Object[] args) {
+                        MemoryError e = null;
+                        if (error != null) {
+                            e = new MemoryError(error.getMessage());
+                        }
+                        else {
+                            assert args.length == 3;
+                            JSON.toByteArray(buf, offs, size, args[0]);
+                            e = toMemoryError(addr, args[1], args[2]);
+                        }
+                        done.doneMemory(token, e);
+                    }
+                }.token;
+        }
+
+        public IToken set(final Number addr, int word_size,
+                byte[] buf, int offs, int size, int mode, final DoneMemory done) {
+            return new MemoryCommand("set", new Object[] {
+                    getID(), addr, word_size, size, mode, new JSON.Binary(buf, offs, size)
+                } ) {
+                    public void done(Exception error, Object[] args) {
+                        MemoryError e = null;
+                        if (error != null) {
+                            e = new MemoryError(error.getMessage());
+                        }
+                        else {
+                            assert args.length == 2;
+                            e = toMemoryError(addr, args[0], args[1]);
+                        }
+                        done.doneMemory(token, e);
+                    }
+                }.token;
+        }
+        
+        public String toString() {
+            return "[Memory Context " + props.toString() + "]";
+        }
+    }
+
+    public MemoryProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public void addListener(final MemoryListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("contextAdded")) {
+                        assert args.length == 1;
+                        listener.contextAdded(toContextArray(args[0]));
+                    }
+                    else if (name.equals("contextChanged")) {
+                        assert args.length == 1;
+                        listener.contextChanged(toContextArray(args[0]));
+                    }
+                    else if (name.equals("contextRemoved")) {
+                        assert args.length == 1;
+                        listener.contextRemoved(toStringArray(args[0]));
+                    }
+                    else if (name.equals("memoryChanged")) {
+                        assert args.length == 2;
+                        listener.memoryChanged((String)args[0],
+                                toAddrArray(args[1]), toSizeArray(args[1]));
+                    }
+                    else {
+                        throw new IOException("Memory service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+
+    public void removeListener(MemoryListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+
+    public IToken getContext(String context_id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ context_id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                MemContext ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new MemContext((Map<String,Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+    
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, arr);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+    
+    private abstract class MemoryCommand extends Command {
+        
+        MemoryCommand(String cmd, Object[] args) {
+            super(channel, MemoryProxy.this, cmd, args);
+        }
+
+        @SuppressWarnings("unchecked")
+        MemoryError toMemoryError(Number addr, Object data, Object ranges) {
+            if (data == null) return null;
+            Map<String,Object> map = (Map<String,Object>)data;
+            Integer code = (Integer)map.get(IErrorReport.ERROR_CODE);
+            String cmd = getCommandString();
+            if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
+            MemoryError e = new MemoryErrorReport(
+                    "TCF command exception:" +
+                    "\nCommand: " + cmd +
+                    "\nException: " + toErrorString(data) +
+                    "\nError code: " + code,
+                    map, addr, ranges);
+            Object caused_by = map.get(IErrorReport.ERROR_CAUSED_BY);
+            if (caused_by != null) e.initCause(toError(caused_by, false));
+            return e;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private MemoryContext[] toContextArray(Object o) {
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        if (c == null) return new MemoryContext[0];
+        int n = 0;
+        MemoryContext[] ctx = new MemoryContext[c.size()];
+        for (Iterator<Map<String,Object>> i = c.iterator(); i.hasNext();) {
+            ctx[n++] = new MemContext(i.next());
+        }
+        return ctx;
+    }
+
+    @SuppressWarnings("unchecked")
+    private long[] toSizeArray(Object o) {
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        if (c == null) return null;
+        long[] a = new long[c.size()];
+        int n = 0;
+        for (Map<String,Object> m : c) {
+            Number sz = (Number)m.get("size");
+            a[n++] = sz == null ? 0 : sz.longValue();
+        }
+        return a;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Number[] toAddrArray(Object o) {
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        if (c == null) return null;
+        Number[] a = new Number[c.size()];
+        int n = 0;
+        for (Map<String,Object> m : c) {
+            a[n++] = (Number)m.get("addr");
+        }
+        return a;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IProcesses;
+
+
+public class ProcessesProxy implements IProcesses {
+    
+    private final IChannel channel;
+    private final Map<ProcessesListener,IChannel.IEventListener> listeners =
+        new HashMap<ProcessesListener,IChannel.IEventListener>();
+    
+    private class ProcessContext implements IProcesses.ProcessContext {
+
+        private final Map<String,Object> props;
+        
+        ProcessContext(Map<String,Object> props) {
+            this.props = props;
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENTID);
+        }
+
+        public boolean canTerminate() {
+            Boolean b = (Boolean)props.get(PROP_CAN_TERMINATE);
+            return b != null && b.booleanValue();
+        }
+
+        public String getName() {
+            return (String)props.get(PROP_NAME);
+        }
+
+        public boolean isAttached() {
+            Boolean b = (Boolean)props.get(PROP_ATTACHED);
+            return b != null && b.booleanValue();
+        }
+
+        public IToken attach(final DoneCommand done) {
+            return new Command(channel, ProcessesProxy.this,
+                    "attach", new Object[]{ getID() }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 1;
+                        error = toError(args[0]);
+                    }
+                    done.doneCommand(token, error);
+                }
+            }.token;
+        }
+
+        public IToken detach(final DoneCommand done) {
+            return new Command(channel, ProcessesProxy.this,
+                    "detach", new Object[]{ getID() }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 1;
+                        error = toError(args[0]);
+                    }
+                    done.doneCommand(token, error);
+                }
+            }.token;
+        }
+
+        public IToken terminate(final DoneCommand done) {
+            return new Command(channel, ProcessesProxy.this,
+                    "terminate", new Object[]{ getID() }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 1;
+                        error = toError(args[0]);
+                    }
+                    done.doneCommand(token, error);
+                }
+            }.token;
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public String toString() {
+            return "[Processes Context " + props.toString() + "]";
+        }
+    }
+    
+    public ProcessesProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public void addListener(final ProcessesListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("exited")) {
+                        assert args.length == 2;
+                        listener.exited((String)args[0], ((Number)args[1]).intValue());
+                    }
+                    else {
+                        throw new IOException("Processes service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+
+    public void removeListener(ProcessesListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+
+    public IToken getChildren(String parent_context_id, boolean attached_only, final DoneGetChildren done) {
+        return new Command(channel, this,
+                "getChildren", new Object[]{ parent_context_id, attached_only }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] ids = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    ids = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, ids);
+            }
+        }.token;
+    }
+
+    public IToken getContext(String id, final DoneGetContext done) {
+        return new Command(channel, this,
+                "getContext", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                ProcessContext ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new ProcessContext((Map<String, Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getEnvironment(final DoneGetEnvironment done) {
+        return new Command(channel, this, "getEnvironment", null) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                Map<String,String> env = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    env = toEnvMap(args[1]);
+                }
+                done.doneGetEnvironment(token, error, env);
+            }
+        }.token;
+    }
+
+    public IToken start(String directory, String file,
+            String[] command_line, Map<String,String> environment,
+            boolean attach, final DoneStart done) {
+        return new Command(channel, this,
+                "start", new Object[]{ directory, file, command_line,
+                toEnvStringArray(environment), attach }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                ProcessContext ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new ProcessContext((Map<String, Object>)args[1]);
+                }
+                done.doneStart(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getSignalList(String context_id, final DoneGetSignalList done) {
+        return new Command(channel, ProcessesProxy.this,
+                "getSignalList", new Object[]{ context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                Collection<Map<String,Object>> list = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    list = toSignalList(args[1]);
+                }
+                done.doneGetSignalList(token, error, list);
+            }
+        }.token;
+    }
+
+    public IToken getSignalMask(String context_id, final DoneGetSignalMask done) {
+        return new Command(channel, ProcessesProxy.this,
+                "getSignalMask", new Object[]{ context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                int dont_stop = 0;
+                int dont_pass = 0;
+                int pending = 0;
+                if (error == null) {
+                    assert args.length == 4;
+                    error = toError(args[0]);
+                    if (args[1] != null) dont_stop = ((Number)args[1]).intValue();
+                    if (args[2] != null) dont_pass = ((Number)args[2]).intValue();
+                    if (args[3] != null) pending = ((Number)args[3]).intValue();
+                }
+                done.doneGetSignalMask(token, error, dont_stop, dont_pass, pending);
+            }
+        }.token;
+    }
+
+    public IToken setSignalMask(String context_id, int dont_stop, int dont_pass, final DoneCommand done) {
+        return new Command(channel, ProcessesProxy.this,
+                "setSignalMask", new Object[]{ context_id, dont_stop, dont_pass }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    public IToken signal(String context_id, long signal, final DoneCommand done) {
+        return new Command(channel, ProcessesProxy.this,
+                "signal", new Object[]{ context_id, signal }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneCommand(token, error);
+            }
+        }.token;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+
+    private static String[] toEnvStringArray(Map<String,String> m) {
+        if (m == null) return new String[0];
+        int n = 0;
+        String[] arr = new String[m.size()];
+        for (String s : m.keySet()) {
+            arr[n++] = s + "=" + m.get(s);
+        }
+        return arr;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static Map<String,String> toEnvMap(Object o) {
+        Map<String,String> m = new HashMap<String,String>();
+        if (o == null) return m;
+        Collection<String> c = (Collection<String>)o;
+        for (String s : c) {
+            int i = s.indexOf('=');
+            if (i >= 0) m.put(s.substring(0, i), s.substring(i + 1));
+            else m.put(s, "");
+        }
+        return m;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static Collection<Map<String,Object>> toSignalList(Object o) {
+        if (o == null) return null;
+        return (Collection<Map<String,Object>>)o;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IRegisters;
+
+
+public class RegistersProxy implements IRegisters {
+
+    private final IChannel channel;
+    private final Map<RegistersListener,IChannel.IEventListener> listeners =
+        new HashMap<RegistersListener,IChannel.IEventListener>();
+    
+    private class Context implements RegistersContext {
+        
+        private final Map<String,Object> props;
+        
+        Context(Map<String,Object> props) {
+            this.props = props;
+        }
+
+        public int[] getBitNumbers() {
+            return toIntArray(props.get(PROP_BITS));
+        }
+
+        public String getDescription() {
+            return (String)props.get(PROP_DESCRIPTION);
+        }
+
+        public int getFirstBitNumber() {
+            Number n = (Number)props.get(PROP_FIST_BIT);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getName() {
+            return (String)props.get(PROP_NAME);
+        }
+
+        public NamedValue[] getNamedValues() {
+            return toValuesArray(props.get(PROP_VALUES));
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENT_ID);
+        }
+        
+        public int getSize() {
+            Number n = (Number)props.get(PROP_SIZE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public boolean hasSideEffects() {
+            Boolean n = (Boolean)props.get(PROP_SIDE_EFFECTS);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isBigEndian() {
+            Boolean n = (Boolean)props.get(PROP_BIG_ENDIAN);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isFloat() {
+            Boolean n = (Boolean)props.get(PROP_FLOAT);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isLeftToRight() {
+            Boolean n = (Boolean)props.get(PROP_LEFT_TO_RIGHT);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isReadOnce() {
+            Boolean n = (Boolean)props.get(PROP_READ_ONCE);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isReadable() {
+            Boolean n = (Boolean)props.get(PROP_READBLE);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isVolatile() {
+            Boolean n = (Boolean)props.get(PROP_VOLATILE);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isWriteOnce() {
+            Boolean n = (Boolean)props.get(PROP_WRITE_ONCE);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        public boolean isWriteable() {
+            Boolean n = (Boolean)props.get(PROP_WRITEABLE);
+            if (n == null) return false;
+            return n.booleanValue();
+        }
+
+        @SuppressWarnings("unchecked")
+        public Collection<String> canSearch() {
+            return (Collection<String>)props.get(PROP_CAN_SEARCH);
+        }
+
+        public Number getMemoryAddress() {
+            return (Number)props.get(PROP_MEMORY_ADDRESS);
+        }
+
+        public String getMemoryContext() {
+            return (String)props.get(PROP_MEMORY_CONTEXT);
+        }
+
+        public String getProcessID() {
+            return (String)props.get(PROP_PROCESS_ID);
+        }
+
+        public String getRole() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        public IToken get(final DoneGet done) {
+            return new Command(channel, RegistersProxy.this, "get",
+                    new Object[]{ getID() }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    byte[] val = null;
+                    if (error == null) {
+                        assert args.length == 2;
+                        error = toError(args[0]);
+                        val = JSON.toByteArray(args[1]);
+                    }
+                    done.doneGet(token, error, val);
+                }
+            }.token;
+        }
+
+        public IToken set(byte[] value, final DoneSet done) {
+            return new Command(channel, RegistersProxy.this, "set",
+                    new Object[]{ getID(), new JSON.Binary(value, 0, value.length) }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 1;
+                        error = toError(args[0]);
+                    }
+                    done.doneSet(token, error);
+                }
+            }.token;
+        }
+
+        public IToken search(Map<String,Object> filter, final DoneSearch done) {
+            return new Command(channel, RegistersProxy.this, "search",
+                    new Object[]{ getID(), filter }) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    String[][] paths = null;
+                    if (error == null) {
+                        assert args.length == 2;
+                        error = toError(args[0]);
+                        paths = toPathArray(args[1]);
+                    }
+                    done.doneSearch(token, error, paths);
+                }
+            }.token;
+        }
+        
+        public String toString() {
+            return "[Registers Context " + props.toString() + "]";
+        }
+    }
+    
+    public RegistersProxy(IChannel channel) {
+        this.channel = channel;
+    }
+    
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken getContext(String id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Context ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getm(Location[] locs, final DoneGet done) {
+        return new Command(channel, this, "getm", new Object[]{ locs }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                byte[] val = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    val = JSON.toByteArray(args[1]);
+                }
+                done.doneGet(token, error, val);
+            }
+        }.token;
+    }
+
+    public IToken setm(Location[] locs, byte[] value, final DoneSet done) {
+        return new Command(channel, this, "setm",
+                new Object[]{ locs, new JSON.Binary(value, 0, value.length) }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneSet(token, error);
+            }
+        }.token;
+    }
+    
+    public void addListener(final RegistersListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("contextChanged")) {
+                        listener.contextChanged();
+                    }
+                    else if (name.equals("registerChanged")) {
+                        assert args.length == 1;
+                        listener.registerChanged((String)args[0]);
+                    }
+                    else {
+                        throw new IOException("Registers service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+
+    public void removeListener(RegistersListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private int[] toIntArray(Object o) {
+        if (o == null) return null;
+        Collection<Number> c = (Collection<Number>)o;
+        int i = 0;
+        int[] arr = new int[c.size()];
+        for (Number n : c) arr[i++] = n.intValue();
+        return arr;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private String[][] toPathArray(Object o) {
+        if (o == null) return null;
+        Collection<Collection<String>> c = (Collection<Collection<String>>)o;
+        int i = 0;
+        String[][] r = new String[c.size()][];
+        for (Collection<String> p : c) {
+            r[i++] = (String[])p.toArray(new String[p.size()]);
+        }
+        return r;
+    }
+    
+    private static class NamedValueInfo implements NamedValue {
+        
+        private final String desc;
+        private final String name;
+        private final byte[] value;
+        
+        NamedValueInfo(Map<String,Object> m) {
+            desc = (String)m.get("Description");
+            name = (String)m.get("Name");
+            value = JSON.toByteArray(m.get("Value"));
+        }
+
+        public String getDescription() {
+            return desc;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public byte[] getValue() {
+            return value;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private NamedValue[] toValuesArray(Object o) {
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        if (c == null) return null;
+        int i = 0;
+        NamedValue[] arr = new NamedValue[c.size()];
+        for (final Map<String,Object> m : c) {
+            arr[i++] = new NamedValueInfo(m);
+        }
+        return arr;
+    }
+    
+    static {
+        JSON.addObjectWriter(Location.class, new JSON.ObjectWriter() {
+            public void write(Object o) throws IOException {
+                Location l = (Location)o;
+                JSON.write('[');
+                JSON.writeObject(l.id);
+                JSON.write(',');
+                JSON.writeUInt(l.offs);
+                JSON.write(',');
+                JSON.writeUInt(l.size);
+                JSON.write(']');
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IRunControl;
+
+
+public class RunControlProxy implements IRunControl {
+
+    private final IChannel channel;
+    private final Map<RunControlListener,IChannel.IEventListener> listeners =
+        new HashMap<RunControlListener,IChannel.IEventListener>();
+
+    private class RunContext implements IRunControl.RunControlContext {
+
+        private final Map<String, Object> props;
+
+        RunContext(Map<String, Object> props) {
+            this.props = props;
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENT_ID);
+        }
+
+        public boolean isContainer() {
+            Boolean b = (Boolean)props.get(PROP_IS_CONTAINER);
+            return b != null && b.booleanValue();
+        }
+
+        public boolean hasState() {
+            Boolean b = (Boolean)props.get(PROP_HAS_STATE);
+            return b != null && b.booleanValue();
+        }
+
+        public boolean canResume(int mode) {
+            if (props.containsKey(PROP_CAN_RESUME)) {
+                int b = ((Number)props.get(PROP_CAN_RESUME)).intValue();
+                return (b & (1 << mode)) != 0;
+            }
+            return false;
+        }
+
+        public boolean canCount(int mode) {
+            if (props.containsKey(PROP_CAN_COUNT)) {
+                int b = ((Number)props.get(PROP_CAN_COUNT)).intValue();
+                return (b & (1 << mode)) != 0;
+            }
+            return false;
+        }
+
+        public boolean canSuspend() {
+            Boolean b = (Boolean)props.get(PROP_CAN_SUSPEND);
+            return b != null && b.booleanValue();
+        }
+
+        public boolean canTerminate() {
+            Boolean b = (Boolean)props.get(PROP_CAN_TERMINATE);
+            return b != null && b.booleanValue();
+        }
+
+        public IToken getState(final DoneGetState done) {
+            return new Command(channel, RunControlProxy.this, "getState", new Object[]{ getID() }) {
+                @SuppressWarnings("unchecked")
+                @Override
+                public void done(Exception error, Object[] args) {
+                    boolean susp = false;
+                    String pc = null;
+                    String reason = null;
+                    Map<String,Object> map = null;
+                    if (error == null) {
+                        assert args.length == 5;
+                        error = toError(args[0]);
+                        susp = ((Boolean)args[1]).booleanValue();
+                        if (args[2] != null) pc =  ((Number)args[2]).toString();
+                        reason = (String)args[3];
+                        map = (Map<String,Object>)args[4];
+                    }
+                    done.doneGetState(token, error, susp, pc, reason, map);
+                }
+            }.token;
+        }
+
+        public IToken resume(int mode, int count, DoneCommand done) {
+            return command("resume", new Object[]{ getID(), mode, count }, done);
+        }
+
+        public IToken resume(int mode, int count, Map<String,Object> params, DoneCommand done) {
+            if (params == null) return resume(mode, count, done);
+            return command("resume", new Object[]{ getID(), mode, count, params }, done);
+        }
+
+        public IToken suspend(DoneCommand done) {
+            return command("suspend", new Object[]{ getID() }, done);
+        }
+
+        public IToken terminate(DoneCommand done) {
+            return command("terminate", new Object[]{ getID() }, done);
+        }
+
+        private IToken command(String cmd, Object[] args, final DoneCommand done) {
+            return new Command(channel, RunControlProxy.this, cmd, args) {
+                @Override
+                public void done(Exception error, Object[] args) {
+                    if (error == null) {
+                        assert args.length == 1;
+                        error = toError(args[0]);
+                    }
+                    done.doneCommand(token, error);
+                }
+            }.token;
+        }
+        
+        public String toString() {
+            return "[Run Control Context " + props.toString() + "]";
+        }
+    }
+
+    public RunControlProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public void addListener(final RunControlListener listener) {
+        IChannel.IEventListener l = new IChannel.IEventListener() {
+
+            @SuppressWarnings("unchecked")
+            public void event(String name, byte[] data) {
+                try {
+                    Object[] args = JSON.parseSequence(data);
+                    if (name.equals("contextSuspended")) {
+                        assert args.length == 4;
+                        listener.contextSuspended(
+                                (String)args[0],
+                                args[1] == null ? null : ((Number)args[1]).toString(),
+                                        (String)args[2], (Map<String,Object>)args[3]);
+                    }
+                    else if (name.equals("contextResumed")) {
+                        assert args.length == 1;
+                        listener.contextResumed((String)args[0]);
+                    }
+                    else if (name.equals("contextAdded")) {
+                        assert args.length == 1;
+                        listener.contextAdded(toContextArray(args[0]));
+                    }
+                    else if (name.equals("contextChanged")) {
+                        assert args.length == 1;
+                        listener.contextChanged(toContextArray(args[0]));
+                    }
+                    else if (name.equals("contextRemoved")) {
+                        assert args.length == 1;
+                        listener.contextRemoved(toStringArray(args[0]));
+                    }
+                    else if (name.equals("contextException")) {
+                        assert args.length == 2;
+                        listener.contextException((String)args[0], (String)args[1]);
+                    }
+                    else if (name.equals("containerSuspended")) {
+                        assert args.length == 5;
+                        listener.containerSuspended(
+                                (String)args[0],
+                                args[1] == null ? null : ((Number)args[1]).toString(),
+                                        (String)args[2], (Map)args[3],
+                                        toStringArray(args[4]));
+                    }
+                    else if (name.equals("containerResumed")) {
+                        assert args.length == 1;
+                        listener.containerResumed(toStringArray(args[0]));
+                    }
+                    else {
+                        throw new IOException("RunControl service: unknown event: " + name);
+                    }
+                }
+                catch (Throwable x) {
+                    channel.terminate(x);
+                }
+            }
+        };
+        channel.addEventListener(this, l);
+        listeners.put(listener, l);
+    }
+    
+    public void removeListener(RunControlListener listener) {
+        IChannel.IEventListener l = listeners.remove(listener);
+        if (l != null) channel.removeEventListener(this, l);
+    }
+
+    public IToken getContext(String context_id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ context_id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                RunControlContext ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new RunContext((Map<String, Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, arr);
+            }
+        }.token;
+    }
+
+    @SuppressWarnings("unchecked")
+    private RunControlContext[] toContextArray(Object o) {
+        if (o == null) return null;
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        int n = 0;
+        RunControlContext[] ctx = new RunControlContext[c.size()];
+        for (Map<String, Object> m : c) ctx[n++] = new RunContext(m);
+        return ctx;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IStackTrace;
+
+
+public class StackTraceProxy implements IStackTrace {
+
+    private final IChannel channel;
+
+    private class Context implements StackTraceContext {
+
+        private final Map<String,Object> props;
+
+        Context(Map<String,Object> props) {
+            if (props == null) props = new HashMap<String,Object>();
+            this.props = props;
+        }
+
+        public Number getArgumentsAddress() {
+            return (Number)props.get(PROP_ARGUMENTS_ADDRESS);
+        }
+
+        public int getArgumentsCount() {
+            Number n = (Number)props.get(PROP_ARGUMENTS_COUNT);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public Number getFrameAddress() {
+            return (Number)props.get(PROP_FRAME_ADDRESS);
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getName() {
+            return (String)props.get(PROP_NAME);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENT_ID);
+        }
+
+        public Number getReturnAddress() {
+            return (Number)props.get(PROP_RETURN_ADDRESS);
+        }
+
+        public Number getInstructionAddress() {
+            return (Number)props.get(PROP_INSTRUCTION_ADDRESS);
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+    }
+
+    public StackTraceProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken getContext(String[] id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                StackTraceContext[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[1]);
+                    arr = toContextArray(args[0]);
+                }
+                done.doneGetContext(token, error, arr);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    @SuppressWarnings("unchecked")
+    private StackTraceContext[] toContextArray(Object o) {
+        if (o == null) return null;
+        Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)o;
+        int n = 0;
+        StackTraceContext[] ctx = new StackTraceContext[c.size()];
+        for (Map<String,Object> m : c) ctx[n++] = new Context(m);
+        return ctx;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/StreamsProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IStreams;
+
+public class StreamsProxy implements IStreams {
+
+    private final IChannel channel;
+    private final Map<StreamsListener,IChannel.IEventListener> listeners =
+        new HashMap<StreamsListener,IChannel.IEventListener>();
+
+    public StreamsProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public IToken connect(String stream_id, final DoneConnect done) {
+        return new Command(channel, this, "connect", new Object[]{ stream_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneConnect(token, error);
+            }
+        }.token;
+    }
+
+    public IToken disconnect(String stream_id, final DoneDisconnect done) {
+        return new Command(channel, this, "disconnect", new Object[]{ stream_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneDisconnect(token, error);
+            }
+        }.token;
+    }
+
+    public IToken eos(String stream_id, final DoneEOS done) {
+        return new Command(channel, this, "eos", new Object[]{ stream_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneEOS(token, error);
+            }
+        }.token;
+    }
+
+    public IToken read(String stream_id, int size, final DoneRead done) {
+        return new Command(channel, this, "read", new Object[]{ stream_id, size }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                int lost_size = 0;
+                byte data[] = null;
+                boolean eos = false;
+                if (error == null) {
+                    assert args.length == 4;
+                    data = JSON.toByteArray(args[0]);
+                    error = toError(args[1]);
+                    lost_size = ((Number)args[2]).intValue();
+                    eos = ((Boolean)args[3]).booleanValue();
+                }
+                done.doneRead(token, error, lost_size, data, eos);
+            }
+        }.token;
+    }
+
+    public IToken subscribe(String stream_type, final StreamsListener listener, final DoneSubscribe done) {
+        return new Command(channel, this, "subscribe", new Object[]{ stream_type }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                if (error == null) {
+                    IChannel.IEventListener l = new IChannel.IEventListener() {
+
+                        public void event(String name, byte[] data) {
+                            try {
+                                Object[] args = JSON.parseSequence(data);
+                                if (name.equals("created")) {
+                                    if (args.length == 3) {
+                                        listener.created((String)args[0], (String)args[1], (String)args[2]);
+                                    }
+                                    else {
+                                        assert args.length == 2;
+                                        listener.created((String)args[0], (String)args[1], null);
+                                    }
+                                }
+                                else if (name.equals("disposed")) {
+                                    assert args.length == 2;
+                                    listener.disposed((String)args[0], (String)args[1]);
+                                }
+                                else {
+                                    throw new IOException("Streams service: unknown event: " + name);
+                                }
+                            }
+                            catch (Throwable x) {
+                                channel.terminate(x);
+                            }
+                        }
+                    };
+                    listeners.put(listener, l);
+                    channel.addEventListener(StreamsProxy.this, l);
+                }
+                done.doneSubscribe(token, error);
+            }
+        }.token;
+    }
+
+    public IToken unsubscribe(String stream_type, final StreamsListener listener, final DoneUnsubscribe done) {
+        return new Command(channel, this, "unsubscribe", new Object[]{ stream_type }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                if (error == null) {
+                    IChannel.IEventListener l = listeners.remove(listener);
+                    if (l != null) channel.removeEventListener(StreamsProxy.this, l);
+                }
+                done.doneUnsubscribe(token, error);
+            }
+        }.token;
+    }
+
+    public IToken write(String stream_id, byte[] buf, int offset, int size, final DoneWrite done) {
+        return new Command(channel, this, "write", new Object[]{ stream_id, size, new JSON.Binary(buf, offset, size) }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                if (error == null) {
+                    assert args.length == 1;
+                    error = toError(args[0]);
+                }
+                done.doneWrite(token, error);
+            }
+        }.token;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,156 @@
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.ISymbols;
+
+public class SymbolsProxy implements ISymbols {
+
+    private final IChannel channel;
+    
+    private class Context implements Symbol {
+        
+        private final byte[] value;
+        private final Map<String,Object> props;
+        
+        Context(Map<String,Object> props) {
+            this.props = props;
+            value = JSON.toByteArray(props.get(PROP_VALUE));
+        }
+
+        public Number getAddress() {
+            return (Number)props.get(PROP_ADDRESS);
+        }
+
+        public String getBaseTypeID() {
+            return (String)props.get(PROP_BASE_TYPE_ID);
+        }
+
+        public String getExeContextID() {
+            return (String)props.get(PROP_EXE_ID);
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getIndexTypeID() {
+            return (String)props.get(PROP_INDEX_TYPE_ID);
+        }
+
+        public int getLength() {
+            Number n = (Number)props.get(PROP_LENGTH);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public String getName() {
+            return (String)props.get(PROP_NAME);
+        }
+
+        public int getOffset() {
+            Number n = (Number)props.get(PROP_OFFSET);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public Map<String,Object> getProperties() {
+            return props;
+        }
+
+        public int getSize() {
+            Number n = (Number)props.get(PROP_SIZE);
+            if (n == null) return 0;
+            return n.intValue();
+        }
+
+        public SymbolClass getSymbolClass() {
+            Number n = (Number)props.get(PROP_SYMBOL_CLASS);
+            if (n != null) {
+                switch (n.intValue()) {
+                case 1: return SymbolClass.value;
+                case 2: return SymbolClass.reference;
+                case 3: return SymbolClass.function;
+                case 4: return SymbolClass.type;
+                }
+            }
+            return SymbolClass.unknown;
+        }
+
+        public TypeClass getTypeClass() {
+            Number n = (Number)props.get(PROP_TYPE_CLASS);
+            if (n != null) {
+                switch (n.intValue()) {
+                case 1: return TypeClass.cardinal;
+                case 2: return TypeClass.integer;
+                case 3: return TypeClass.real;
+                case 4: return TypeClass.pointer;
+                case 5: return TypeClass.array;
+                case 6: return TypeClass.composite;
+                case 7: return TypeClass.enumeration;
+                case 8: return TypeClass.function;
+                }
+            }
+            return TypeClass.unknown;
+        }
+
+        public String getTypeID() {
+            return (String)props.get(PROP_TYPE_ID);
+        }
+
+        public byte[] getValue() {
+            return value;
+        }
+    }
+
+    public SymbolsProxy(IChannel channel) {
+        this.channel = channel;
+    }
+    
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken getContext(String id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                Context ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] lst = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    lst = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, lst);
+            }
+        }.token;
+    }
+
+    @SuppressWarnings("unchecked")
+    private String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.services.remote;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Command;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.ISysMonitor;
+
+
+public class SysMonitorProxy implements ISysMonitor {
+
+    private final IChannel channel;
+
+    private class SysMonitorContext implements ISysMonitor.SysMonitorContext {
+
+        private final Map<String, Object> props;
+
+        SysMonitorContext(Map<String, Object> props) {
+            this.props = props;
+        }
+
+        public String getID() {
+            return (String)props.get(PROP_ID);
+        }
+
+        public String getCurrentWorkingDirectory() {
+            return (String)props.get(PROP_CWD);
+        }
+
+        public String getFile() {
+            return (String)props.get(PROP_FILE);
+        }
+
+        public String getParentID() {
+            return (String)props.get(PROP_PARENTID);
+        }
+
+        public String getRoot() {
+            return (String)props.get(PROP_ROOT);
+        }
+
+        public String getGroupName() {
+            return (String)props.get(PROP_GROUPNAME);
+        }
+
+        public long getPGRP() {
+            if (!props.containsKey(PROP_PGRP)) return -1;
+            return ((Number)props.get(PROP_PGRP)).longValue();
+        }
+
+        public long getPID() {
+            if (!props.containsKey(PROP_PID)) return -1;
+            return ((Number)props.get(PROP_PID)).longValue();
+        }
+
+        public long getPPID() {
+            if (!props.containsKey(PROP_PPID)) return -1;
+            return ((Number)props.get(PROP_PPID)).longValue();
+        }
+
+        public long getRSS() {
+            if (!props.containsKey(PROP_RSS)) return -1;
+            return ((Number)props.get(PROP_RSS)).longValue();
+        }
+
+        public String getState() {
+            return (String)props.get(PROP_STATE);
+        }
+
+        public long getTGID() {
+            if (!props.containsKey(PROP_TGID)) return -1;
+            return ((Number)props.get(PROP_TGID)).longValue();
+        }
+
+        public long getTracerPID() {
+            if (!props.containsKey(PROP_TRACERPID)) return -1;
+            return ((Number)props.get(PROP_TRACERPID)).longValue();
+        }
+
+        public long getUGID() {
+            if (!props.containsKey(PROP_UGID)) return -1;
+            return ((Number)props.get(PROP_UGID)).longValue();
+        }
+
+        public long getUID() {
+            if (!props.containsKey(PROP_UID)) return -1;
+            return ((Number)props.get(PROP_UID)).longValue();
+        }
+
+        public String getUserName() {
+            return (String)props.get(PROP_USERNAME);
+        }
+
+        public long getVSize() {
+            if (!props.containsKey(PROP_VSIZE)) return -1;
+            return ((Number)props.get(PROP_VSIZE)).longValue();
+        }
+
+        public long getPSize() {
+            if (!props.containsKey(PROP_PSIZE)) return -1;
+            return ((Number)props.get(PROP_PSIZE)).longValue();
+        }
+
+        public Map<String, Object> getProperties() {
+            return props;
+        }
+        
+        public String toString() {
+            return "[Sys Monitor Context " + props.toString() + "]";
+        }
+    }
+
+    public SysMonitorProxy(IChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public IToken getChildren(String parent_context_id, final DoneGetChildren done) {
+        return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetChildren(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken getContext(String id, final DoneGetContext done) {
+        return new Command(channel, this, "getContext", new Object[]{ id }) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void done(Exception error, Object[] args) {
+                SysMonitorContext ctx = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    if (args[1] != null) ctx = new SysMonitorContext((Map<String, Object>)args[1]);
+                }
+                done.doneGetContext(token, error, ctx);
+            }
+        }.token;
+    }
+
+    public IToken getCommandLine(String id, final DoneGetCommandLine done) {
+        return new Command(channel, this, "getCommandLine", new Object[]{ id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetCommandLine(token, error, arr);
+            }
+        }.token;
+    }
+
+    public IToken getEnvironment(String id, final DoneGetEnvironment done) {
+        return new Command(channel, this, "getEnvironment", new Object[]{ id }) {
+            @Override
+            public void done(Exception error, Object[] args) {
+                String[] arr = null;
+                if (error == null) {
+                    assert args.length == 2;
+                    error = toError(args[0]);
+                    arr = toStringArray(args[1]);
+                }
+                done.doneGetEnvironment(token, error, arr);
+            }
+        }.token;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static String[] toStringArray(Object o) {
+        if (o == null) return null;
+        Collection<String> c = (Collection<String>)o;
+        return (String[])c.toArray(new String[c.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,973 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.core.ServiceManager;
+import org.eclipse.tm.internal.tcf.core.Token;
+import org.eclipse.tm.internal.tcf.core.TransportManager;
+import org.eclipse.tm.internal.tcf.services.local.LocatorService;
+import org.eclipse.tm.internal.tcf.services.remote.GenericProxy;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+
+/**
+ * Abstract implementation of IChannel interface.
+ *  
+ * AbstractChannel implements communication link connecting two end points (peers).
+ * The channel asynchronously transmits messages: commands, results and events.
+ * 
+ * Clients can subclass AbstractChannel to support particular transport (wire) protocol.
+ * Also, see StreamChannel for stream oriented transport protocols.
+ */
+public abstract class AbstractChannel implements IChannel {
+
+    public interface TraceListener {
+        
+        public void onMessageReceived(char type, String token,
+                String service, String name, byte[] data);
+        
+        public void onMessageSent(char type, String token,
+                String service, String name, byte[] data);
+        
+        public void onChannelClosed(Throwable error);
+    }
+    
+    public interface Proxy {
+        
+        public void onCommand(IToken token, String service, String name, byte[] data);
+        
+        public void onEvent(String service, String name, byte[] data);
+
+        public void onChannelClosed(Throwable error);
+    }
+
+    private static class Message {
+        final char type;
+        Token token;
+        String service;
+        String name;
+        byte[] data;
+
+        boolean is_sent;
+        boolean is_canceled;
+
+        Collection<TraceListener> trace;
+        
+        Message(char type) {
+            this.type = type;
+        }
+
+        @Override
+        public String toString() {
+            try {
+                StringBuffer bf = new StringBuffer();
+                bf.append('[');;
+                bf.append(type);
+                if (token != null) {
+                    bf.append(' ');
+                    bf.append(token.getID());
+                }
+                if (service != null) {
+                    bf.append(' ');
+                    bf.append(service);
+                }
+                if (name != null) {
+                    bf.append(' ');
+                    bf.append(name);
+                }
+                if (data != null) {
+                    int i = 0;
+                    while (i < data.length) {
+                        int j = i;
+                        while (j < data.length && data[j] != 0) j++;
+                        bf.append(' ');
+                        bf.append(new String(data, i, j - i, "UTF8"));
+                        if (j < data.length && data[j] == 0) j++;
+                        i = j;
+                    }
+                }
+                bf.append(']');
+                return bf.toString();
+            }
+            catch (Exception x) {
+                return x.toString();
+            }
+        }
+    }
+
+    private static IChannelListener[] listeners_array = new IChannelListener[4];
+
+    private final LinkedList<String> redirect_queue = new LinkedList<String>();
+    private final Map<Class<?>,IService> local_service_by_class = new HashMap<Class<?>,IService>();
+    private final Map<Class<?>,IService> remote_service_by_class = new HashMap<Class<?>,IService>();
+    private final Map<String,IService> local_service_by_name = new HashMap<String,IService>();
+    private final Map<String,IService> remote_service_by_name = new HashMap<String,IService>();
+    private final LinkedList<Message> out_queue = new LinkedList<Message>();
+    private final Collection<IChannelListener> channel_listeners = new ArrayList<IChannelListener>();
+    private final Map<String,IChannel.IEventListener[]> event_listeners = new HashMap<String,IChannel.IEventListener[]>();
+    private final Map<String,IChannel.ICommandServer> command_servers = new HashMap<String,IChannel.ICommandServer>();
+    private final Map<String,Message> out_tokens = new HashMap<String,Message>();
+    private final Thread inp_thread;
+    private final Thread out_thread;
+    private boolean notifying_channel_opened;
+    private boolean registered_with_trasport;
+    private boolean shutdown;
+    private int state = STATE_OPENNING;
+    private IToken redirect_command;
+    private final IPeer local_peer;
+    private IPeer remote_peer;
+    private Proxy proxy;
+    private boolean zero_copy;
+
+    private static final int pending_command_limit = 32;
+    private int local_congestion_level = -100;
+    private int remote_congestion_level = -100;
+    private long local_congestion_time;
+    private int local_congestion_cnt;
+    private Collection<TraceListener> trace_listeners;
+    
+    public static final int
+        EOS = -1, // End Of Stream
+        EOM = -2; // End Of Message
+    
+    protected AbstractChannel(IPeer remote_peer) {
+        this(LocatorService.getLocalPeer(), remote_peer);
+    }
+
+    protected AbstractChannel(IPeer local_peer, IPeer remote_peer) {
+        assert Protocol.isDispatchThread();
+        this.remote_peer = remote_peer;
+        this.local_peer = local_peer;
+
+        inp_thread = new Thread() {
+
+            final byte[] empty_byte_array = new byte[0];
+            byte[] buf = new byte[1024];
+            byte[] eos;
+
+            private void error() throws IOException {
+                throw new IOException("Protocol syntax error");
+            }
+
+            private byte[] readBytes(int end) throws IOException {
+                int len = 0;
+                for (;;) {
+                    int n = read();
+                    if (n <= 0) {
+                        if (n == end) break;
+                        if (n == EOM) throw new IOException("Unexpected end of message");
+                        if (n < 0) throw new IOException("Communication channel is closed by remote peer");
+                    }
+                    if (len >= buf.length) {
+                        byte[] tmp = new byte[buf.length * 2];
+                        System.arraycopy(buf, 0, tmp, 0, len);
+                        buf = tmp;
+                    }
+                    buf[len++] = (byte)n;
+                }
+                if (len == 0) return empty_byte_array;
+                byte[] res = new byte[len];
+                System.arraycopy(buf, 0, res, 0, len);
+                return res;
+            }
+
+            private String readString() throws IOException {
+                int len = 0;
+                for (;;) {
+                    int n = read();
+                    if (n <= 0) {
+                        if (n == 0) break;
+                        if (n == EOM) throw new IOException("Unexpected end of message");
+                        if (n < 0) throw new IOException("Communication channel is closed by remote peer");
+                    }
+                    if (len >= buf.length) {
+                        byte[] tmp = new byte[buf.length * 2];
+                        System.arraycopy(buf, 0, tmp, 0, len);
+                        buf = tmp;
+                    }
+                    buf[len++] = (byte)n;
+                }
+                return new String(buf, 0, len, "UTF8");
+            }
+
+            @Override
+            public void run() {
+                try {
+                    while (true) {
+                        int n = read();
+                        if (n == EOM) continue;
+                        if (n == EOS) {
+                            eos = readBytes(EOM);
+                            break;
+                        }
+                        final Message msg = new Message((char)n);
+                        if (read() != 0) error();
+                        switch (msg.type) {
+                        case 'C':
+                            msg.token = new Token(readBytes(0));
+                            msg.service = readString();
+                            msg.name = readString();
+                            msg.data = readBytes(EOM);
+                            break;
+                        case 'P':
+                        case 'R':
+                        case 'N':
+                            msg.token = new Token(readBytes(0));
+                            msg.data = readBytes(EOM);
+                            break;
+                        case 'E':
+                            msg.service = readString();
+                            msg.name = readString();
+                            msg.data = readBytes(EOM);
+                            break;
+                        case 'F':
+                            msg.data = readBytes(EOM);
+                            break;
+                        default:
+                            error();
+                        }
+                        Protocol.invokeLater(new Runnable() {
+                            public void run() {
+                                handleInput(msg);
+                            }
+                        });
+                        int delay = local_congestion_level;
+                        if (delay > 0) sleep(delay);
+                    }
+                    Protocol.invokeLater(new Runnable() {
+                        public void run() {
+                            if (out_tokens.isEmpty()) {
+                                close();
+                            }
+                            else {
+                                IOException x = new IOException("Connection reset by peer");
+                                try {
+                                    Object[] args = JSON.parseSequence(eos);
+                                    if (args.length > 0 && args[0] != null) {
+                                        x = new IOException(Command.toErrorString(args[0]));
+                                    }
+                                }
+                                catch (IOException e) {
+                                    x = e;
+                                }
+                                terminate(x);
+                            }
+                        }
+                    });
+                }
+                catch (final Throwable x) {
+                    Protocol.invokeLater(new Runnable() {
+                        public void run() {
+                            terminate(x);
+                        }
+                    });
+                }
+            }
+        };
+
+        out_thread = new Thread() {
+
+            @Override
+            public void run() {
+                try {
+                    while (true) {
+                        Message msg = null;
+                        boolean last = false;
+                        synchronized (out_queue) {
+                            while (out_queue.isEmpty()) out_queue.wait();
+                            msg = out_queue.removeFirst();
+                            if (msg == null) break;
+                            last = out_queue.isEmpty();
+                            if (msg.is_canceled) {
+                                if (last) flush();
+                                continue;
+                            }
+                            msg.is_sent = true;
+                        }
+                        if (msg.trace != null) {
+                            final Message m = msg;
+                            Protocol.invokeLater(new Runnable() {
+                                public void run() {
+                                    for (TraceListener l : m.trace) {
+                                        try {
+                                            l.onMessageSent(m.type, m.token == null ? null : m.token.getID(),
+                                                    m.service, m.name, m.data);
+                                        }
+                                        catch (Throwable x) {
+                                            Protocol.log("Exception in channel listener", x);
+                                        }
+                                    }
+                                }
+                            });
+                        }
+                        write(msg.type);
+                        write(0);
+                        if (msg.token != null) {
+                            write(msg.token.getBytes());
+                            write(0);
+                        }
+                        if (msg.service != null) {
+                            write(msg.service.getBytes("UTF8"));
+                            write(0);
+                        }
+                        if (msg.name != null) {
+                            write(msg.name.getBytes("UTF8"));
+                            write(0);
+                        }
+                        if (msg.data != null) {
+                            write(msg.data);
+                        }
+                        write(EOM);
+                        int delay = 0;
+                        int level = remote_congestion_level;
+                        if (level > 0) delay = level * 10;
+                        if (last || delay > 0) flush();
+                        if (delay > 0) sleep(delay);
+                        else yield();
+                    }
+                    write(EOS);
+                    write(EOM);
+                    flush();
+                }
+                catch (final Throwable x) {
+                    Protocol.invokeLater(new Runnable() {
+                        public void run() {
+                            terminate(x);
+                        }
+                    });
+                }
+            }
+        };
+        inp_thread.setName("TCF Channel Receiver");
+        out_thread.setName("TCF Channel Transmitter");
+    }
+
+    protected void start() {
+        assert Protocol.isDispatchThread();
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                try {
+                    if (proxy != null) return;
+                    if (state == STATE_CLOSED) return;
+                    ServiceManager.onChannelCreated(AbstractChannel.this, local_service_by_name);
+                    makeServiceByClassMap(local_service_by_name, local_service_by_class);
+                    Object[] args = new Object[]{ local_service_by_name.keySet() };  
+                    sendEvent(Protocol.getLocator(), "Hello", JSON.toJSONSequence(args));
+                }
+                catch (IOException x) {
+                    terminate(x);
+                }
+            }
+        });
+        inp_thread.start();
+        out_thread.start();
+    }
+
+    /**
+     * Redirect this channel to given peer using this channel remote peer locator service as a proxy.
+     * @param peer_id - peer that will become new remote communication endpoint of this channel
+     */
+    public void redirect(final String peer_id) {
+        assert Protocol.isDispatchThread();
+        if (state == STATE_OPENNING) {
+            redirect_queue.add(peer_id);
+        }
+        else {
+            assert state == STATE_OPEN;
+            assert redirect_command == null;
+            try {
+                final ILocator l = (ILocator)remote_service_by_class.get(ILocator.class);
+                if (l == null) throw new IOException("Cannot redirect channel: peer " +
+                        remote_peer.getID() + " has no locator service");
+                final IPeer peer = l.getPeers().get(peer_id);
+                if (peer == null) {
+                    // Peer not found, must wait for a while until peer is discovered or time out
+                    final boolean[] found = new boolean[1];
+                    Protocol.invokeLater(ILocator.DATA_RETENTION_PERIOD / 3, new Runnable() {
+                        public void run() {
+                            if (found[0]) return;
+                            terminate(new Exception("Peer " + peer_id + " not found"));
+                        }
+                    });
+                    l.addListener(new ILocator.LocatorListener() {
+                        public void peerAdded(IPeer peer) {
+                            if (peer.getID().equals(peer_id)) {
+                                found[0] = true;
+                                state = STATE_OPEN;
+                                l.removeListener(this);
+                                redirect(peer_id);
+                            }
+                        }
+                        public void peerChanged(IPeer peer) {
+                        }
+
+                        public void peerHeartBeat(String id) {
+                        }
+
+                        public void peerRemoved(String id) {
+                        }
+                    });
+                }
+                else {
+                    redirect_command = l.redirect(peer_id, new ILocator.DoneRedirect() {
+                        public void doneRedirect(IToken token, Exception x) {
+                            assert redirect_command == token;
+                            redirect_command = null;
+                            if (state != STATE_OPENNING) return;
+                            if (x != null) terminate(x);
+                            remote_peer = peer;
+                            remote_service_by_class.clear();
+                            remote_service_by_name.clear();
+                            event_listeners.clear();
+                        }
+                    });
+                }
+                state = STATE_OPENNING;
+            }
+            catch (Throwable x) {
+                terminate(x);
+            }
+        }
+    }
+
+    private void makeServiceByClassMap(Map<String,IService> by_name, Map<Class<?>,IService> by_class) {
+        for (IService service : by_name.values()) {
+            for (Class<?> fs : service.getClass().getInterfaces()) {
+                if (fs.equals(IService.class)) continue;
+                if (!IService.class.isAssignableFrom(fs)) continue;
+                by_class.put(fs, service);
+            }
+        }
+    }
+
+    public final int getState() {
+        return state;
+    }
+
+    public void addChannelListener(IChannelListener listener) {
+        assert Protocol.isDispatchThread();
+        assert listener != null;
+        channel_listeners.add(listener);
+    }
+
+    public void removeChannelListener(IChannelListener listener) {
+        assert Protocol.isDispatchThread();
+        channel_listeners.remove(listener);
+    }
+    
+    public void addTraceListener(TraceListener listener) {
+        if (trace_listeners == null) {
+            trace_listeners = new ArrayList<TraceListener>();
+        }
+        else {
+            trace_listeners = new ArrayList<TraceListener>(trace_listeners);
+        }
+        trace_listeners.add(listener);
+    }
+    
+    public void removeTraceListener(TraceListener listener) {
+        trace_listeners = new ArrayList<TraceListener>(trace_listeners);
+        trace_listeners.remove(listener);
+        if (trace_listeners.isEmpty()) trace_listeners = null;
+    }
+
+    public void addEventListener(IService service, IChannel.IEventListener listener) {
+        assert Protocol.isDispatchThread();
+        IChannel.IEventListener[] list = event_listeners.get(service.getName());
+        IChannel.IEventListener[] next = new IChannel.IEventListener[list == null ? 1 : list.length + 1];
+        if (list != null) System.arraycopy(list, 0, next, 0, list.length);
+        next[next.length - 1] = listener;
+        event_listeners.put(service.getName(), next);
+    }
+
+    public void removeEventListener(IService service, IChannel.IEventListener listener) {
+        assert Protocol.isDispatchThread();
+        IChannel.IEventListener[] list = event_listeners.get(service.getName());
+        for (int i = 0; i < list.length; i++) {
+            if (list[i] == listener) {
+                if (list.length == 1) {
+                    event_listeners.remove(service.getName());
+                }
+                else {
+                    IChannel.IEventListener[] next = new IChannel.IEventListener[list.length - 1];
+                    System.arraycopy(list, 0, next, 0, i);
+                    System.arraycopy(list, i + 1, next, i, next.length - i);
+                    event_listeners.put(service.getName(), next);
+                }
+                return;
+            }
+        }
+    }
+
+    public void addCommandServer(IService service, IChannel.ICommandServer listener) {
+        assert Protocol.isDispatchThread();
+        if (command_servers.put(service.getName(), listener) != null) {
+            throw new Error("Only one command server per service is allowed");
+        }
+    }
+
+    public void removeCommandServer(IService service, IChannel.ICommandServer listener) {
+        assert Protocol.isDispatchThread();
+        if (command_servers.remove(service.getName()) != listener) {
+            throw new Error("Invalid command server");
+        }
+    }
+
+    private void sendEndOfStream() {
+        if (shutdown) return;
+        shutdown = true;
+        synchronized (out_queue) {
+            out_queue.clear();
+            out_queue.add(0, null);
+            out_queue.notify();
+        }
+    }
+    
+    public void close() {
+        assert Protocol.isDispatchThread();
+        try {
+            sendEndOfStream();
+            out_thread.join(10000);
+            stop();
+            inp_thread.join(10000);
+            terminate(null);
+        }
+        catch (Exception x) {
+            terminate(x);
+        }
+    }
+
+    public void terminate(final Throwable error) {
+        assert Protocol.isDispatchThread();
+        sendEndOfStream();
+        if (state == STATE_CLOSED) return;
+        state = STATE_CLOSED;
+        if (error != null && remote_peer instanceof AbstractPeer) {
+            ((AbstractPeer)remote_peer).onChannelTerminated();
+        }
+        if (registered_with_trasport) {
+            registered_with_trasport = false;
+            TransportManager.channelClosed(this, error);
+        }
+        if (proxy != null) {
+            try {
+                proxy.onChannelClosed(error);
+            }
+            catch (Throwable x) {
+                Protocol.log("Exception in channel listener", x);
+            }
+        }
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                if (!out_tokens.isEmpty()) {
+                    Exception x = null;
+                    if (error instanceof Exception) x = (Exception)error;
+                    else if (error != null) x = new Exception(error);
+                    else x = new IOException("Channel is closed");
+                    for (Message msg : out_tokens.values()) {
+                        try {
+                            String s = msg.toString();
+                            if (s.length() > 72) s = s.substring(0, 72) + "...]";
+                            IOException y = new IOException("Command " + s + " aborted");
+                            y.initCause(x);
+                            msg.token.getListener().terminated(msg.token, y);
+                        }
+                        catch (Throwable e) {
+                            Protocol.log("Exception in command listener", e);
+                        }
+                    }
+                    out_tokens.clear();
+                }
+                if (channel_listeners.isEmpty()) {
+                    Protocol.log("TCF channel terminated", error);
+                }
+                else {
+                    listeners_array = channel_listeners.toArray(listeners_array);
+                    for (IChannelListener l : listeners_array) {
+                        if (l == null) break;
+                        try {
+                            l.onChannelClosed(error);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Exception in channel listener", x);
+                        }
+                    }
+                }
+                if (trace_listeners != null) {
+                    for (TraceListener l : trace_listeners) {
+                        try {
+                            l.onChannelClosed(error);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Exception in channel listener", x);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    public int getCongestion() {
+        assert Protocol.isDispatchThread();
+        int level = out_tokens.size() * 100 / pending_command_limit - 100;
+        if (remote_congestion_level > level) level = remote_congestion_level;
+        if (level > 100) level = 100;
+        return level;
+    }
+
+    public IPeer getLocalPeer() {
+        assert Protocol.isDispatchThread();
+        return local_peer;
+    }
+
+    public IPeer getRemotePeer() {
+        assert Protocol.isDispatchThread();
+        return remote_peer;
+    }
+    
+    public Collection<String> getLocalServices() {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return local_service_by_name.keySet();
+    }
+
+    public Collection<String> getRemoteServices() {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return remote_service_by_name.keySet();
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <V extends IService> V getLocalService(Class<V> cls) {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return (V)local_service_by_class.get(cls);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <V extends IService> V getRemoteService(Class<V> cls) {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return (V)remote_service_by_class.get(cls);
+    }
+    
+    public <V extends IService> void setServiceProxy(Class<V> service_interface, IService service_proxy) {
+        if (!notifying_channel_opened) new Error("setServiceProxe() can be called only from channel open call-back");
+        if (!(remote_service_by_name.get(service_proxy.getName()) instanceof GenericProxy)) throw new Error("Proxy already set"); 
+        if (remote_service_by_class.get(service_interface) != null) throw new Error("Proxy already set");
+        remote_service_by_class.put(service_interface, service_proxy);
+        remote_service_by_name.put(service_proxy.getName(), service_proxy);
+    }
+    
+    public IService getLocalService(String service_name) {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return local_service_by_name.get(service_name);
+    }
+
+    public IService getRemoteService(String service_name) {
+        assert Protocol.isDispatchThread();
+        assert state != STATE_OPENNING;
+        return remote_service_by_name.get(service_name);
+    }
+    
+    public void setProxy(Proxy proxy, Collection<String> services) throws IOException {
+        this.proxy = proxy;
+        sendEvent(Protocol.getLocator(), "Hello", JSON.toJSONSequence(new Object[]{ services }));
+        local_service_by_class.clear();
+        local_service_by_name.clear();
+    }
+    
+    private void addToOutQueue(Message msg) {
+        msg.trace = trace_listeners;
+        synchronized (out_queue) {
+            out_queue.add(msg);
+            out_queue.notify();
+        }
+    }
+
+    public IToken sendCommand(IService service, String name, byte[] args, ICommandListener listener) {
+        assert Protocol.isDispatchThread();
+        if (state == STATE_OPENNING) throw new Error("Channel is waiting for Hello message");
+        if (state == STATE_CLOSED) throw new Error("Channel is closed");
+        final Message msg = new Message('C');
+        msg.service = service.getName();
+        msg.name = name;
+        msg.data = args;
+        Token token = new Token(listener) {
+            @Override
+            public boolean cancel() {
+                assert Protocol.isDispatchThread();
+                if (state != STATE_OPEN) return false;
+                synchronized (out_queue) {
+                    if (msg.is_sent) return false;
+                    msg.is_canceled = true;
+                }
+                out_tokens.remove(msg.token.getID());
+                return true;
+            }
+        };
+        msg.token = token;
+        out_tokens.put(token.getID(), msg);
+        addToOutQueue(msg);
+        return token;
+    }
+
+    public void sendProgress(IToken token, byte[] results) {
+        assert Protocol.isDispatchThread();
+        if (state != STATE_OPEN) throw new Error("Channel is closed");
+        Message msg = new Message('P');
+        msg.data = results;
+        msg.token = (Token)token;
+        addToOutQueue(msg);
+    }
+
+    public void sendResult(IToken token, byte[] results) {
+        assert Protocol.isDispatchThread();
+        if (state != STATE_OPEN) throw new Error("Channel is closed");
+        Message msg = new Message('R');
+        msg.data = results;
+        msg.token = (Token)token;
+        addToOutQueue(msg);
+    }
+
+    public void rejectCommand(IToken token) {
+        assert Protocol.isDispatchThread();
+        if (state != STATE_OPEN) throw new Error("Channel is closed");
+        Message msg = new Message('N');
+        msg.token = (Token)token;
+        addToOutQueue(msg);
+    }
+
+    public void sendEvent(IService service, String name, byte[] args) {
+        assert Protocol.isDispatchThread();
+        if (!(state == STATE_OPEN || state == STATE_OPENNING && service instanceof ILocator)) {
+            throw new Error("Channel is closed");
+        }
+        Message msg = new Message('E');
+        msg.service = service.getName();
+        msg.name = name;
+        msg.data = args;
+        addToOutQueue(msg);
+    }
+    
+    public boolean isZeroCopySupported() {
+        return zero_copy;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void handleInput(Message msg) {
+        assert Protocol.isDispatchThread();
+        if (state == STATE_CLOSED) return;
+        if (trace_listeners != null) {
+            for (TraceListener l : trace_listeners) {
+                try {
+                    l.onMessageReceived(msg.type,
+                            msg.token != null ? msg.token.getID() : null,
+                            msg.service, msg.name, msg.data);
+                }
+                catch (Throwable x) {
+                    Protocol.log("Exception in trace listener", x);
+                }
+            }
+        }
+        try {
+            Token token = null;
+            switch (msg.type) {
+            case 'P':
+            case 'R':
+            case 'N':
+                String token_id = msg.token.getID();
+                Message cmd = msg.type == 'P' ? out_tokens.get(token_id) : out_tokens.remove(token_id);
+                if (cmd == null) throw new Exception("Invalid token received: " + token_id);
+                token = cmd.token;
+                break;
+            }
+            switch (msg.type) {
+            case 'C':
+                if (state == STATE_OPENNING) {
+                    throw new IOException("Received command " + msg.service + "." + msg.name + " before Hello message");
+                }
+                if (proxy != null) {
+                    proxy.onCommand(msg.token, msg.service, msg.name, msg.data);
+                }
+                else {
+                    token = msg.token;
+                    IChannel.ICommandServer cmds = command_servers.get(msg.service);
+                    if (cmds != null) {
+                        cmds.command(token, msg.name, msg.data);
+                    }
+                    else {
+                        rejectCommand(token);
+                    }
+                }
+                break;
+            case 'P':
+                token.getListener().progress(token, msg.data);
+                sendCongestionLevel();
+                break;
+            case 'R':
+                token.getListener().result(token, msg.data);
+                sendCongestionLevel();
+                break;
+            case 'N':
+                token.getListener().terminated(token, new ErrorReport(
+                        "Command is not recognized", IErrorReport.TCF_ERROR_INV_COMMAND));
+                break;
+            case 'E':
+                boolean hello = msg.service.equals(ILocator.NAME) && msg.name.equals("Hello");
+                if (hello) {
+                    remote_service_by_name.clear();
+                    remote_service_by_class.clear();
+                    ServiceManager.onChannelOpened(this, (Collection<String>)JSON.parseSequence(msg.data)[0], remote_service_by_name);
+                    makeServiceByClassMap(remote_service_by_name, remote_service_by_class);
+                    zero_copy = remote_service_by_name.containsKey("ZeroCopy");
+                }
+                if (proxy != null && state == STATE_OPEN) {
+                    proxy.onEvent(msg.service, msg.name, msg.data);
+                }
+                else if (hello) {
+                    assert state == STATE_OPENNING;                    
+                    state = STATE_OPEN;
+                    assert redirect_command == null;
+                    if (redirect_queue.size() > 0) {
+                        redirect(redirect_queue.removeFirst());
+                    }
+                    else {
+                        notifying_channel_opened = true;
+                        if (!registered_with_trasport) {
+                            TransportManager.channelOpened(this);
+                            registered_with_trasport = true;
+                        }
+                        listeners_array = channel_listeners.toArray(listeners_array);
+                        for (IChannelListener l : listeners_array) {
+                            if (l == null) break;
+                            try {
+                                l.onChannelOpened();
+                            }
+                            catch (Throwable x) {
+                                Protocol.log("Exception in channel listener", x);
+                            }
+                        }
+                        notifying_channel_opened = false;
+                    }
+                }
+                else {
+                    IChannel.IEventListener[] list = event_listeners.get(msg.service);
+                    if (list != null) {
+                        for (int i = 0; i < list.length; i++) {
+                            list[i].event(msg.name, msg.data);
+                        }
+                    }
+                    sendCongestionLevel();
+                }
+                break;
+            case 'F':
+                int len = msg.data.length;
+                if (len > 0 && msg.data[len - 1] == 0) len--;
+                remote_congestion_level = Integer.parseInt(new String(msg.data, 0, len, "ASCII"));
+                break;
+            default:
+                assert false;
+                break;
+            }
+        }
+        catch (Throwable x) {
+            terminate(x);
+        }
+    }
+
+    private void sendCongestionLevel() throws IOException {
+        if (++local_congestion_cnt < 8) return;
+        local_congestion_cnt = 0;
+        if (state != STATE_OPEN) return;
+        long time = System.currentTimeMillis();
+        if (time - local_congestion_time < 500) return;
+        assert Protocol.isDispatchThread();
+        int level = Protocol.getCongestionLevel();
+        if (level == local_congestion_level) return;
+        int i = (level - local_congestion_level) / 8;
+        if (i != 0) level = local_congestion_level + i;
+        local_congestion_time = time;
+        synchronized (out_queue) {
+            Message msg = out_queue.isEmpty() ? null : out_queue.get(0);
+            if (msg == null || msg.type != 'F') {
+                msg = new Message('F');
+                out_queue.add(0, msg);
+                out_queue.notify();
+            }
+            StringBuilder buffer = new StringBuilder();
+            buffer.append(local_congestion_level);
+            buffer.append((char)0); // 0 terminate
+            msg.data = buffer.toString().getBytes("ASCII");
+            msg.trace = trace_listeners;
+            local_congestion_level = level;
+        }
+    }
+
+    /**
+     * Read one byte from the channel input stream.
+     * @return next data byte or EOS (-1) if end of stream is reached,
+     * or EOM (-2) if end of message is reached.
+     * @throws IOException
+     */
+    protected abstract int read() throws IOException;
+
+    /**
+     * Write one byte into the channel output stream.
+     * The method argument can be one of two special values:
+     *   EOS (-1) end of stream marker;
+     *   EOM (-2) end of message marker. 
+     * The stream can put the byte into a buffer instead of transmitting it right away.
+     * @param n - the data byte.
+     * @throws IOException
+     */
+    protected abstract void write(int n) throws IOException;
+
+    /**
+     * Flush the channel output stream.
+     * All buffered data should be transmitted immediately.
+     * @throws IOException
+     */
+    protected abstract void flush() throws IOException;
+
+    /**
+     * Stop (close) channel underlying streams.
+     * If a thread is blocked by read() or write(), it should be
+     * resumed (or interrupted).  
+     * @throws IOException
+     */
+    protected abstract void stop() throws IOException;
+
+    /**
+     * Write array of bytes into the channel output stream.
+     * The stream can put bytes into a buffer instead of transmitting it right away.
+     * @param buf
+     * @throws IOException
+     */
+    protected void write(byte[] buf) throws IOException {
+        assert Thread.currentThread() == out_thread;
+        for (int i = 0; i < buf.length; i++) write(buf[i]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractPeer.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.core.TransportManager;
+import org.eclipse.tm.internal.tcf.services.local.LocatorService;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.tcf.services.ILocator.LocatorListener;
+
+/**
+ * Abstract implementation of IPeer interface.
+ */
+public class AbstractPeer implements IPeer {
+
+    private final Map<String, String> ro_attrs;
+    private final Map<String, String> rw_attrs;
+    
+    private long last_heart_beat_time;
+    
+    public AbstractPeer(Map<String,String> attrs) {
+        assert Protocol.isDispatchThread();
+        if (attrs != null) {
+            rw_attrs = new HashMap<String, String>(attrs);
+        }
+        else {
+            rw_attrs = new HashMap<String, String>();
+        }
+        ro_attrs = Collections.unmodifiableMap(rw_attrs);
+        assert getID() != null;
+        LocatorService.addPeer(this);
+    }
+    
+    void onChannelTerminated() {
+        // A channel to this peer was terminated:
+        // not delaying next heart beat helps client to recover much faster. 
+        last_heart_beat_time = 0;
+    }
+
+    public void updateAttributes(Map<String,String> attrs) {
+        boolean equ = true;
+        assert attrs.get(ATTR_ID).equals(rw_attrs.get(ATTR_ID));
+        for (Iterator<String> i = rw_attrs.keySet().iterator(); i.hasNext();) {
+            String key = i.next();
+            if (!rw_attrs.get(key).equals(attrs.get(key))) {
+                equ = false;
+                break;
+            }
+        }
+        for (Iterator<String> i = attrs.keySet().iterator(); i.hasNext();) {
+            String key = i.next();
+            if (!attrs.get(key).equals(rw_attrs.get(key))) {
+                equ = false;
+                break;
+            }
+        }
+        long time = System.currentTimeMillis();
+        if (!equ) {
+            rw_attrs.clear();
+            rw_attrs.putAll(attrs);
+            for (LocatorListener l : LocatorService.getListeners()) {
+                try {
+                    l.peerChanged(this);
+                }
+                catch (Throwable x) {
+                    Protocol.log("Unhandled exception in Locator listener", x);
+                }
+            }
+            try {
+                Object[] args = { rw_attrs };
+                Protocol.sendEvent(ILocator.NAME, "peerChanged", JSON.toJSONSequence(args));
+            }
+            catch (IOException x) {
+                Protocol.log("Locator: failed to send 'peerChanged' event", x);
+            }
+            last_heart_beat_time = time;
+        }
+        else if (last_heart_beat_time + ILocator.DATA_RETENTION_PERIOD / 4 < time) {
+            for (LocatorListener l : LocatorService.getListeners()) {
+                try {
+                    l.peerHeartBeat(attrs.get(ATTR_ID));
+                }
+                catch (Throwable x) {
+                    Protocol.log("Unhandled exception in Locator listener", x);
+                }
+            }
+            try {
+                Object[] args = { rw_attrs.get(ATTR_ID) };
+                Protocol.sendEvent(ILocator.NAME, "peerHeartBeat", JSON.toJSONSequence(args));
+            }
+            catch (IOException x) {
+                Protocol.log("Locator: failed to send 'peerHeartBeat' event", x);
+            }
+            last_heart_beat_time = time;
+        }
+    }
+    
+    public void sendPeerAddedEvent() {
+        for (LocatorListener l : LocatorService.getListeners()) {
+            try {
+                l.peerAdded(this);
+            }
+            catch (Throwable x) {
+                Protocol.log("Unhandled exception in Locator listener", x);
+            }
+        }
+        try {
+            Object[] args = { rw_attrs };
+            Protocol.sendEvent(ILocator.NAME, "peerAdded", JSON.toJSONSequence(args));
+        }
+        catch (IOException x) {
+            Protocol.log("Locator: failed to send 'peerAdded' event", x);
+        }
+        last_heart_beat_time = System.currentTimeMillis();
+    }
+
+    public void sendPeerRemovedEvent() {
+        for (LocatorListener l : LocatorService.getListeners()) {
+            try {
+                l.peerRemoved(rw_attrs.get(ATTR_ID));
+            }
+            catch (Throwable x) {
+                Protocol.log("Unhandled exception in Locator listener", x);
+            }
+        }
+        try {
+            Object[] args = { rw_attrs.get(ATTR_ID) };
+            Protocol.sendEvent(ILocator.NAME, "peerRemoved", JSON.toJSONSequence(args));
+        }
+        catch (IOException x) {
+            Protocol.log("Locator: failed to send 'peerRemoved' event", x);
+        }
+    }
+
+    public void dispose() {
+        assert Protocol.isDispatchThread();
+        TransportManager.peerDisposed(this);
+        LocatorService.removePeer(this);
+    }
+
+    public Map<String,String> getAttributes() {
+        assert Protocol.isDispatchThread();
+        return ro_attrs;
+    }
+
+    public String getID() {
+        assert Protocol.isDispatchThread();
+        return ro_attrs.get(ATTR_ID);
+    }
+
+    public String getName() {
+        assert Protocol.isDispatchThread();
+        return ro_attrs.get(ATTR_NAME);
+    }
+
+    public String getOSName() {
+        assert Protocol.isDispatchThread();
+        return ro_attrs.get(ATTR_OS_NAME);
+    }
+
+    public String getTransportName() {
+        assert Protocol.isDispatchThread();
+        return ro_attrs.get(ATTR_TRANSPORT_NAME);
+    }
+    
+    public IChannel openChannel() {
+        return TransportManager.openChannel(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/Base64.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+/**
+ * Methods for translating Base64 encoded strings to byte arrays and back.
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Base64 {
+    
+    public static char[] toBase64(byte[] buf, int pos, int len) {
+        char[] out_buf = new char[4 * ((len + 2) / 3)];
+        int end = pos + len;
+        int out_pos = 0;
+        while (pos < end) {
+            int byte0 = buf[pos++] & 0xff;
+            out_buf[out_pos++] = int2char[byte0 >> 2];
+            if (pos == end) {
+                out_buf[out_pos++] = int2char[(byte0 << 4) & 0x3f];
+                out_buf[out_pos++] = '=';
+                out_buf[out_pos++] = '=';
+            }
+            else {
+                int byte1 = buf[pos++] & 0xff;
+                out_buf[out_pos++] = int2char[(byte0 << 4) & 0x3f | (byte1 >> 4)];
+                if (pos == end) {
+                    out_buf[out_pos++] = int2char[(byte1 << 2) & 0x3f];
+                    out_buf[out_pos++] = '=';
+                }
+                else {
+                    int byte2 = buf[pos++] & 0xff;
+                    out_buf[out_pos++] = int2char[(byte1 << 2) & 0x3f | (byte2 >> 6)];
+                    out_buf[out_pos++] = int2char[byte2 & 0x3f];
+                }
+            }
+        }
+        assert out_pos == out_buf.length;
+        return out_buf;
+    }
+    
+    public static void toByteArray(byte[] buf, int offs, int size, char[] inp) {
+        int out_pos = offs;
+        if (inp != null) {
+            int inp_len = inp.length;
+            if (inp_len % 4 != 0) {
+                throw new IllegalArgumentException(
+                        "BASE64 string length must be a multiple of four.");
+            }
+            int out_len = inp_len / 4 * 3;
+            if (inp_len > 0 && inp[inp_len - 1] == '=') {
+                out_len--;
+                if (inp[inp_len - 2] == '=') {
+                    out_len--;
+                }
+            }
+            if (out_len > size) {
+                throw new IllegalArgumentException(
+                        "BASE64 data array is longer then destination buffer.");
+            }
+            int inp_pos = 0;
+            while (inp_pos < inp_len) {
+                int n0, n1, n2, n3;
+                char ch0 = inp[inp_pos++];
+                char ch1 = inp[inp_pos++];
+                char ch2 = inp[inp_pos++];
+                char ch3 = inp[inp_pos++];
+                if (ch0 >= char2int.length || (n0 = char2int[ch0]) < 0) {
+                    throw new IllegalArgumentException("Illegal character " + ch0);
+                }
+                if (ch1 >= char2int.length || (n1 = char2int[ch1]) < 0) {
+                    throw new IllegalArgumentException("Illegal character " + ch1);
+                }
+                buf[out_pos++] = (byte)((n0 << 2) | (n1 >> 4));
+                if (ch2 == '=') break;
+                if (ch2 >= char2int.length || (n2 = char2int[ch2]) < 0) {
+                    throw new IllegalArgumentException("Illegal character " + ch2);
+                }
+                buf[out_pos++] = (byte)((n1 << 4) | (n2 >> 2));
+                if (ch3 == '=') break;
+                if (ch3 >= char2int.length || (n3 = char2int[ch3]) < 0) {
+                    throw new IllegalArgumentException("Illegal character " + ch3);
+                }
+                buf[out_pos++] = (byte)((n2 << 6) | n3);
+            }
+            assert out_pos == offs + out_len;
+        }
+        while (out_pos < offs + size) buf[out_pos++] = 0;
+    }
+
+    public static byte[] toByteArray(char[] inp) {
+        int inp_len = inp.length;
+        int out_len = inp_len / 4 * 3;
+        if (inp_len > 0 && inp[inp_len - 1] == '=') {
+            out_len--;
+            if (inp[inp_len - 2] == '=') {
+                out_len--;
+            }
+        }
+        byte[] buf = new byte[out_len];
+        toByteArray(buf, 0, buf.length, inp);
+        return buf;
+    }
+    
+    /*
+     * See RFC 2045.
+     */
+    private static final char int2char[] = {
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+        'w', 'x', 'y', 'z', '0', '1', '2', '3',
+        '4', '5', '6', '7', '8', '9', '+', '/'
+    };
+
+    /*
+     * See RFC 2045
+     */
+    private static final byte char2int[] = {
+        -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, -1, -1, -1, -1, -1,
+        -1, -1, -1, 62, -1, -1, -1, 63,
+        52, 53, 54, 55, 56, 57, 58, 59,
+        60, 61, -1, -1, -1, -1, -1, -1,
+        -1,  0,  1,  2,  3,  4,  5,  6,
+         7,  8,  9, 10, 11, 12, 13, 14,
+        15, 16, 17, 18, 19, 20, 21, 22,
+        23, 24, 25, -1, -1, -1, -1, -1,
+        -1, 26, 27, 28, 29, 30, 31, 32,
+        33, 34, 35, 36, 37, 38, 39, 40,
+        41, 42, 43, 44, 45, 46, 47, 48,
+        49, 50, 51
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ChannelTCP.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * ChannelTCP is a IChannel implementation that works on top of TCP sockets as a transport.
+ */
+public class ChannelTCP extends StreamChannel {
+
+    private Socket socket;
+    private InputStream inp;
+    private OutputStream out;
+    private boolean started;
+    private boolean closed;
+
+    private static SSLContext ssl_context;
+
+    public static void setSSLContext(SSLContext ssl_context) {
+        ChannelTCP.ssl_context = ssl_context;
+    }
+
+    public ChannelTCP(IPeer remote_peer, final String host, final int port, final boolean ssl) {
+        super(remote_peer);
+        Thread thread = new Thread() {
+            public void run() {
+                try {
+                    if (ssl) {
+                        if (ssl_context == null) throw new Exception("SSL context is not set");
+                        socket = ssl_context.getSocketFactory().createSocket(host, port);
+                    }
+                    else {
+                        socket = new Socket(host, port);
+                    }
+                    socket.setTcpNoDelay(true);
+                    socket.setKeepAlive(true);
+                    if (ssl) ((SSLSocket)socket).startHandshake();
+                    inp = new BufferedInputStream(socket.getInputStream());
+                    out = new BufferedOutputStream(socket.getOutputStream());
+                    onSocketConnected(null);
+                }
+                catch (final Exception x) {
+                    onSocketConnected(x);
+                }
+            }
+        };
+        thread.setName("TCF Socket Connect");
+        thread.start();
+    }
+
+    public ChannelTCP(IPeer remote_peer, String host, int port) {
+        this(remote_peer, host, port, false);
+    }
+
+    public ChannelTCP(IPeer local_peer, IPeer remote_peer, Socket socket) throws IOException {
+        super(local_peer, remote_peer);
+        this.socket = socket;
+        socket.setTcpNoDelay(true);
+        inp = new BufferedInputStream(socket.getInputStream());
+        out = new BufferedOutputStream(socket.getOutputStream());
+        onSocketConnected(null);
+    }
+
+    private void onSocketConnected(final Throwable x) {
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                if (x != null) terminate(x);
+                if (closed) {
+                    try {
+                        if (socket != null) {
+                            socket.close();
+                            if (out != null) out.close();
+                            if (inp != null) inp.close();
+                        }
+                    }
+                    catch (IOException y) {
+                        Protocol.log("Cannot close socket", y);
+                    }
+                }
+                else {
+                    started = true;
+                    start();
+                }
+            }
+        });
+    }
+
+    @Override
+    protected final int get() throws IOException {
+        try {
+            if (closed) return -1;
+            return inp.read();
+        }
+        catch (SocketException x) {
+            if (closed) return -1;
+            throw x;
+        }
+    }
+
+    @Override
+    protected final void put(int b) throws IOException {
+        assert b >= 0 && b <= 0xff;
+        if (closed) return;
+        out.write(b);
+    }
+
+    @Override
+    protected final void put(byte[] buf) throws IOException {
+        if (closed) return;
+        out.write(buf);
+    }
+
+    @Override
+    protected final void flush() throws IOException {
+        if (closed) return;
+        out.flush();
+    }
+
+    @Override
+    protected void stop() throws IOException {
+        closed = true;
+        if (started) {
+            socket.close();
+            out.close();
+            inp.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/Command.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.core.Token;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+
+/**
+ * This is utility class that helps to implement sending a command and receiving
+ * command result over TCF communication channel. The class uses JSON to encode
+ * command arguments and to decode result data.
+ * 
+ * The class also provides support for TCF standard error report encoding.
+ * 
+ * Clients are expected to subclass <code>Command</code> and override <code>done</code> method.
+ * 
+ * Note: most clients don't need to handle protocol commands directly and
+ * can use service APIs instead. Service API does all command encoding/decoding
+ * for a client.
+ * 
+ * Typical usage example:
+ * 
+ *  public IToken getContext(String id, final DoneGetContext done) {
+ *      return new Command(channel, IService.this, "getContext", new Object[]{ id }) {
+ *          @Override
+ *          public void done(Exception error, Object[] args) {
+ *              Context ctx = null;
+ *              if (error == null) {
+ *                  assert args.length == 2;
+ *                  error = toError(args[0]);
+ *                  if (args[1] != null) ctx = new Context(args[1]);
+ *              }
+ *              done.doneGetContext(token, error, ctx);
+ *          }
+ *      }.token;
+ *  }
+ */
+public abstract class Command implements IChannel.ICommandListener {
+    
+    private final IService service;
+    private final String command;
+    private final Object[] args;
+    
+    public final IToken token;
+    
+    private boolean done;
+    
+    private static final SimpleDateFormat timestamp_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+    
+    public Command(IChannel channel, IService service, String command, Object[] args) {
+        this.service = service;
+        this.command = command;
+        this.args = args;
+        IToken t = null;
+        try {
+            boolean zero_copy = ((AbstractChannel)channel).isZeroCopySupported();
+            t = channel.sendCommand(service, command, JSON.toJSONSequence(args, zero_copy), this);
+        }
+        catch (Throwable y) {
+            t = new Token();
+            final Exception x = y instanceof Exception ? (Exception)y : new Exception(y);
+            Protocol.invokeLater(new Runnable() {
+                public void run() {
+                    assert !done;
+                    done = true;
+                    done(x, null);
+                }
+            });
+        }
+        token = t;
+    }
+
+    public void progress(IToken token, byte[] data) {
+        assert this.token == token;
+    }
+
+    public void result(IToken token, byte[] data) {
+        assert this.token == token;
+        Exception error = null;
+        Object[] args = null;
+        try {
+            args = JSON.parseSequence(data);
+        }
+        catch (Exception e) {
+            error = e;
+        }
+        assert !done;
+        done = true;
+        done(error, args);
+    }
+
+    public void terminated(IToken token, Exception error) {
+        assert this.token == token;
+        assert !done;
+        done = true;
+        done(error, null);
+    }
+    
+    public abstract void done(Exception error, Object[] args);
+    
+    public String getCommandString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(service.getName());
+        buf.append(' ');
+        buf.append(command);
+        if (args != null) {
+            for (int i = 0; i < args.length; i++) {
+                buf.append(i == 0 ? " " : ", ");
+                try {
+                    buf.append(JSON.toJSON(args[i]));
+                }
+                catch (IOException x) {
+                    buf.append("***");
+                    buf.append(x.getMessage());
+                    buf.append("***");
+                }
+            }
+        }
+        return buf.toString();
+    }
+    
+    @SuppressWarnings({ "unchecked" })
+    public static String toErrorString(Object data) {
+        if (data == null) return null;
+        Map<String,Object> map = (Map<String,Object>)data;
+        String fmt = (String)map.get(IErrorReport.ERROR_FORMAT);
+        if (fmt != null) {
+            Collection<Object> c = (Collection<Object>)map.get(IErrorReport.ERROR_PARAMS);
+            if (c != null) return new MessageFormat(fmt).format(c.toArray());
+            return fmt;
+        }
+        Number code = (Number)map.get(IErrorReport.ERROR_CODE);
+        if (code != null) {
+            if (code.intValue() == IErrorReport.TCF_ERROR_OTHER) {
+                String alt_org = (String)map.get(IErrorReport.ERROR_ALT_ORG);
+                Number alt_code = (Number)map.get(IErrorReport.ERROR_ALT_CODE);
+                if (alt_org != null && alt_code != null) {
+                    return alt_org + " Error " + alt_code;
+                }
+            }
+            return "TCF Error " + code;
+        }
+        return "Invalid error report format";
+    }
+    
+    static void appendErrorProps(StringBuffer bf, Map<String,Object> map) {
+        Number time = (Number)map.get(IErrorReport.ERROR_TIME);
+        Number code = (Number)map.get(IErrorReport.ERROR_CODE);
+        String service = (String)map.get(IErrorReport.ERROR_SERVICE);
+        Number severity = (Number)map.get(IErrorReport.ERROR_SEVERITY);
+        Number alt_code = (Number)map.get(IErrorReport.ERROR_ALT_CODE);
+        String alt_org = (String)map.get(IErrorReport.ERROR_ALT_ORG);
+        if (time != null) {
+            bf.append('\n');
+            bf.append("Time: ");
+            bf.append(timestamp_format.format(new Date(time.longValue())));
+        }
+        if (severity != null) {
+            bf.append('\n');
+            bf.append("Severity: ");
+            bf.append(toErrorString(map));
+            switch (severity.intValue()) {
+            case IErrorReport.SEVERITY_ERROR: bf.append("Error");
+            case IErrorReport.SEVERITY_FATAL: bf.append("Fatal");
+            case IErrorReport.SEVERITY_WARNING: bf.append("Warning");
+            default: bf.append("Unknown");
+            }
+        }
+        bf.append('\n');
+        bf.append("Error text: ");
+        bf.append(toErrorString(map));
+        bf.append('\n');
+        bf.append("Error code: ");
+        bf.append(code);
+        if (service != null) {
+            bf.append('\n');
+            bf.append("Service: ");
+            bf.append(service);
+        }
+        if (alt_code != null) {
+            bf.append('\n');
+            bf.append("Alt code: ");
+            bf.append(alt_code);
+            if (alt_org != null) {
+                bf.append('\n');
+                bf.append("Alt org: ");
+                bf.append(alt_org);
+            }
+        }
+    }
+    
+    public Exception toError(Object data) {
+        return toError(data, true);
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Exception toError(Object data, boolean include_command_text) {
+        if (data == null) return null;
+        Map<String,Object> map = (Map<String,Object>)data;
+        StringBuffer bf = new StringBuffer();
+        bf.append("TCF error report:");
+        bf.append('\n');
+        if (include_command_text) {
+            String cmd = getCommandString();
+            if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "...";
+            bf.append("Command: ");
+            bf.append(cmd);
+        }
+        appendErrorProps(bf, map);
+        return new ErrorReport(bf.toString(), map);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ErrorReport.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+
+class ErrorReport extends Exception implements IErrorReport {
+    
+    private static final long serialVersionUID = 3687543884858739977L;
+    private final Map<String,Object> attrs;
+    
+    @SuppressWarnings("unchecked")
+    ErrorReport(String msg, Map<String,Object> attrs) {
+        super(msg);
+        this.attrs = attrs;
+        Object caused_by = attrs.get(IErrorReport.ERROR_CAUSED_BY);
+        if (caused_by != null) {
+            Map<String,Object> map = (Map<String,Object>)caused_by;
+            StringBuffer bf = new StringBuffer();
+            bf.append("TCF error report:");
+            bf.append('\n');
+            Command.appendErrorProps(bf, map);
+            initCause(new ErrorReport(bf.toString(), map));
+        }
+    }
+    
+    ErrorReport(String msg, int code) {
+        super(msg);
+        attrs = new HashMap<String,Object>();
+        attrs.put(ERROR_CODE, code);
+        attrs.put(ERROR_TIME, System.currentTimeMillis());
+        attrs.put(ERROR_FORMAT, msg);
+        attrs.put(ERROR_SEVERITY, SEVERITY_ERROR);
+    }
+
+    public int getErrorCode() {
+        Number n = (Number)attrs.get(ERROR_CODE);
+        if (n == null) return 0;
+        return n.intValue();
+    }
+
+    public int getAltCode() {
+        Number n = (Number)attrs.get(ERROR_ALT_CODE);
+        if (n == null) return 0;
+        return n.intValue();
+    }
+
+    public String getAltOrg() {
+        return (String)attrs.get(ERROR_ALT_ORG);
+    }
+
+    public Map<String, Object> getAttributes() {
+        return attrs;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/ServerTCP.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * ServerTCP is a TCP server that is listening for incoming connection requests
+ * and creates TCF communication channels over TCP sockets for such requests.
+ * 
+ * Clients may create objects of this class to become a TCF server.
+ */
+public class ServerTCP extends ServerSocket {
+    
+    private static class ServerPeer extends AbstractPeer {
+        ServerPeer(Map<String,String> attrs) {
+            super(attrs);
+        }
+    }
+    
+    private static class RemotePeer extends AbstractPeer {
+        RemotePeer(Map<String,String> attrs) {
+            super(attrs);
+        }
+    }
+    
+    private final String name;
+    private List<ServerPeer> peers;
+    private Thread thread;
+    
+    public ServerTCP(String name, int port) throws IOException {
+        super(port);
+        this.name = name;
+        peers = new ArrayList<ServerPeer>();
+        Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
+        while (e.hasMoreElements()) {
+            NetworkInterface f = e.nextElement();
+            Enumeration<InetAddress> n = f.getInetAddresses();
+            while (n.hasMoreElements()) {
+                peers.add(getLocalPeer(n.nextElement().getHostAddress()));
+            }
+        }
+        thread = new Thread() {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        final Socket socket = accept();
+                        Protocol.invokeLater(new Runnable() {
+                            public void run() {
+                                try {
+                                    new ChannelTCP(getLocalPeer(socket), getRemotePeer(socket), socket);
+                                }
+                                catch (final Throwable x) {
+                                    Protocol.log("TCF Server: failed to create a channel", x);
+                                }
+                            }
+                        });
+                    }
+                    catch (final Throwable x) {
+                        Protocol.invokeLater(new Runnable() {
+                            public void run() {
+                                Protocol.log("TCF Server thread aborted", x);
+                            }
+                        });
+                        break;
+                    }
+                }
+            }
+        };
+        thread.setName(name);
+        thread.setDaemon(true);
+        thread.start();
+    }
+    
+    private ServerPeer getLocalPeer(String addr) {
+        for (ServerPeer p : peers) {
+            if (addr.equals(p.getAttributes().get(IPeer.ATTR_IP_HOST))) return p;
+        }
+        Map<String,String> attrs = new HashMap<String,String>();
+        attrs.put(IPeer.ATTR_ID, "TCP:" + addr + ":" + getLocalPort());
+        attrs.put(IPeer.ATTR_NAME, name);
+        attrs.put(IPeer.ATTR_OS_NAME, System.getProperty("os.name"));
+        attrs.put(IPeer.ATTR_TRANSPORT_NAME, "TCP");
+        attrs.put(IPeer.ATTR_IP_HOST, addr);
+        attrs.put(IPeer.ATTR_IP_PORT, Integer.toString(getLocalPort()));
+        attrs.put(IPeer.ATTR_PROXY, "");
+        ServerPeer p = new ServerPeer(attrs); 
+        peers.add(p);
+        return p;
+    }
+    
+    private IPeer getLocalPeer(Socket socket) {
+        return getLocalPeer(socket.getLocalAddress().getHostAddress());
+    }
+    
+    private IPeer getRemotePeer(Socket socket) {
+        String addr = socket.getInetAddress().getHostAddress();
+        for (IPeer p : Protocol.getLocator().getPeers().values()) {
+            if (addr.equals(p.getAttributes().get(IPeer.ATTR_IP_HOST))) return p;
+        }
+        Map<String,String> attrs = new HashMap<String,String>();
+        attrs.put(IPeer.ATTR_ID, "TCP:" + addr + ":");
+        attrs.put(IPeer.ATTR_TRANSPORT_NAME, "TCP");
+        attrs.put(IPeer.ATTR_IP_HOST, addr);
+        return new RemotePeer(attrs);
+    }
+    
+    @Override
+    public void close() throws IOException {
+        if (peers != null) {
+            for (ServerPeer s : peers) s.dispose();
+            peers = null;
+        }
+        super.close();
+        if (thread != null) {
+            try {
+                thread.join();
+                thread = null;
+            }
+            catch (InterruptedException e) {
+                throw new InterruptedIOException();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/StreamChannel.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.core;
+
+import java.io.IOException;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+/**
+ * Abstract implementation of IChannel interface for stream oriented transport protocols.
+ *
+ * StreamChannel implements communication link connecting two end points (peers).
+ * The channel asynchronously transmits messages: commands, results and events.
+ * 
+ * StreamChannel uses escape sequences to represent End-Of-Message and End-Of-Stream markers.
+ * 
+ * Clients can subclass StreamChannel to support particular stream oriented transport (wire) protocol.
+ * Also, see ChannelTCP for a concrete IChannel implementation that works on top of TCP sockets as a transport.
+ */
+public abstract class StreamChannel extends AbstractChannel {
+
+    public static final int ESC = 3;
+    
+    private int bin_data_size;
+
+    public StreamChannel(IPeer remote_peer) {
+        super(remote_peer);
+    }
+
+    public StreamChannel(IPeer local_peer, IPeer remote_peer) {
+        super(local_peer, remote_peer);
+    }
+
+    protected abstract int get() throws IOException;
+    protected abstract void put(int n) throws IOException;
+    
+    protected void put(byte[] buf) throws IOException {
+        for (byte b : buf) put(b & 0xff);
+    }
+
+    @Override
+    protected final int read() throws IOException {
+        for (;;) {
+            int res = get();
+            if (res < 0) return EOS;
+            assert res >= 0 && res <= 0xff;
+            if (bin_data_size > 0) {
+                bin_data_size--;
+                return res;
+            }
+            if (res != ESC) return res;
+            int n = get();
+            switch (n) {
+            case 0: return ESC;
+            case 1: return EOM;
+            case 2: return EOS;
+            case 3:
+                for (int i = 0;; i += 7) {
+                    res = get();
+                    bin_data_size |= (res & 0x7f) << i;
+                    if ((res & 0x80) == 0) break;
+                }
+                break;
+            default:
+                if (n < 0) return EOS;
+                assert false;
+            }
+        }
+    }
+
+    @Override
+    protected final void write(int n) throws IOException {
+        switch (n) {
+        case ESC: put(ESC); put(0); break;
+        case EOM: put(ESC); put(1); break;
+        case EOS: put(ESC); put(2); break;
+        default:
+            assert n >= 0 && n <= 0xff;
+            put(n);
+        }
+    }
+
+    @Override
+    protected void write(byte[] buf) throws IOException {
+        if (buf.length > 32 && isZeroCopySupported()) {
+            put(ESC); put(3);
+            int n = buf.length;
+            for (;;) {
+                if (n <= 0x7f) {
+                    put(n);
+                    break;
+                }
+                put((n & 0x7f) | 0x80);
+                n = n >> 7;
+            }
+            put(buf);
+        }
+        else {
+            for (byte b : buf) {
+                int n = b & 0xff;
+                put(n);
+                if (n == ESC) put(0);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+import java.util.Collection;
+
+/**
+ * IChannel represents communication link connecting two end points (peers).
+ * The channel asynchronously transmits messages: commands, results and events.
+ * A single channel may be used to communicate with multiple services.
+ * Multiple channels may be used to connect the same peers, however no command or event
+ * ordering is guaranteed across channels.
+ * 
+ * @noimplement This interface is not intended to be implemented by clients.
+ * Clients can extend abstract implementations of IChannel: AbstractChannel or StreamChannel.
+ */
+
+public interface IChannel {
+
+    /**
+     * Channel state IDs
+     */
+    static final int
+        STATE_OPENNING = 0,
+        STATE_OPEN = 1,
+        STATE_CLOSED = 2;
+
+    /**
+     * @return channel state, see STATE_*
+     */
+    int getState();
+
+    /**
+     * Send command message to remote peer for execution. Commands can be queued
+     * locally before transmission. Sending commands too fast can fill up
+     * communication channel buffers. Calling thread will be blocked until
+     * enough buffer space is freed up by transmitting pending messages.
+     * @param service - a remote service that will be sent the command
+     * @param name - command name
+     * @param args - command arguments encoded into array of bytes
+     * @param done - call back object
+     * @return pending command handle 
+     */
+    IToken sendCommand(IService service, String name, byte[] args, ICommandListener done);
+
+    /**
+     * Command listener interface. Clients implement this interface to
+     * receive command results.  
+     */
+    interface ICommandListener {
+
+        /**
+         * Called when progress message (intermediate result) is received
+         * from remote peer.
+         * @param token - command handle
+         * @param data - progress message arguments encoded into array of bytes
+         */
+        void progress(IToken token, byte[] data);
+
+        /**
+         * Called when command result received from remote peer.
+         * @param token - command handle
+         * @param data - command result message arguments encoded into array of bytes
+         */
+        void result(IToken token, byte[] data);
+
+        /**
+         * Called when command is terminated because communication channel was closed or
+         * command is not recognized by remote peer.
+         * @param token - command handle
+         * @param error - exception that forced the channel to close
+         */
+        void terminated(IToken token, Exception error);
+    }
+
+    /**
+     * Send result message to remote peer. Messages can be queued locally before
+     * transmission. Sending messages too fast can fill up communication channel
+     * buffers. Calling thread will be blocked until enough buffer space is
+     * freed up by transmitting pending messages.
+     * @param token - command handle
+     * @param results - result message arguments encoded into array of bytes
+     */
+    void sendResult(IToken token, byte[] results);
+
+    /**
+     * Reject a command by sending "N" result message to remote peer.
+     * Clients should reject commands that they don't recognize.
+     * Messages can be queued locally before
+     * transmission. Sending messages too fast can fill up communication channel
+     * buffers. Calling thread will be blocked until enough buffer space is
+     * freed up by transmitting pending messages.
+     * @param token - command handle
+     * @param results - result message arguments encoded into array of bytes
+     */
+    void rejectCommand(IToken token);
+
+    /**
+     * Get current level of out-bound traffic congestion.
+     * 
+     * @return integer value in range –100..100, where –100 means no pending
+     *         messages (no traffic), 0 means optimal load, and positive numbers
+     *         indicate level of congestion.
+     * 
+     * Note: in-bound traffic congestion is detected by framework and reported to
+     * remote peer without client needed to be involved. Clients willing to provide
+     * additional data about local congestion should register itself using
+     * Protocol.addCongestionMonitor().
+     */
+    int getCongestion();
+
+    /**
+     * Channel listener interface.
+     */
+    interface IChannelListener {
+
+        /**
+         * Called when a channel is opened or redirected.
+         */
+        void onChannelOpened();
+
+        /**
+         * Called when channel closed. If it is closed because of an error,
+         * ‘error’ parameter will describe the error. ‘error’ is null if channel
+         * is closed normally by calling Channel.close().
+         * @param error - channel exception or null
+         */
+        void onChannelClosed(Throwable error);
+
+        /**
+         * Notifies listeners about channel out-bound traffic congestion level changes.
+         * When level > 0 client should delay sending more messages.
+         * @param level - current congestion level
+         */
+        void congestionLevel(int level);
+    }
+
+    /**
+     * Subscribe a channel listener. The listener will be notified about changes of
+     * channel state and changes of out-bound traffic congestion level.
+     * @param listener - channel listener implementation
+     */
+    void addChannelListener(IChannelListener listener);
+
+    /**
+     * Remove a channel listener.
+     * @param listener - channel listener implementation
+     */
+    void removeChannelListener(IChannelListener listener);
+
+    /**
+     * Command server interface.
+     * This interface is to be implemented by service providers.
+     */
+    interface ICommandServer {
+
+        /**
+         * Called every time a command is received from remote peer.
+         * @param token - command handle
+         * @param name - command name
+         * @param data - command arguments encoded into array of bytes
+         */
+        void command(IToken token, String name, byte[] data);
+    }
+
+    /**
+     * Subscribe a command server. The server will be notified about command
+     * messages received through this channel for given service.
+     * @param service - local service implementation
+     * @param server - implementation of service commands listener 
+     */
+    void addCommandServer(IService service, ICommandServer server);
+
+    /**
+     * Remove a command server.
+     * @param service - local service implementation
+     * @param server - implementation of service commands listener 
+     */
+    void removeCommandServer(IService service, ICommandServer server);
+
+    /**
+     * A generic interface for service event listener.
+     * Services usually define a service specific event listener interface,
+     * which is implemented using this generic listener.
+     * Clients should user service specific listener interface,
+     * unless no such interface is defined. 
+     */
+    interface IEventListener {
+        /**
+         * Called when service event message is received
+         * @param name - event name
+         * @param data - event arguments encode as array of bytes
+         */
+        void event(String name, byte[] data);
+    }
+
+    /**
+     * Subscribe an event listener for given service.
+     * @param service - remote service proxy
+     * @param server - implementation of service event listener 
+     */
+    void addEventListener(IService service, IEventListener listener);
+
+    /**
+     * Unsubscribe an event listener for given service.
+     * @param service - remote service proxy
+     * @param server - implementation of service event listener 
+     */
+    void removeEventListener(IService service, IEventListener listener);
+
+    /**
+     * @return IPeer object representing local endpoint of communication channel.
+     */
+    IPeer getLocalPeer();
+
+    /**
+     * @return IPeer object representing remote endpoint of communication channel.
+     */
+    IPeer getRemotePeer();
+
+    /**
+     * @return collection of services available on local peer.
+     */
+    Collection<String> getLocalServices();
+
+    /**
+     * @return an object representing a service from local peer.
+     * Return null if the service is not available.
+     */
+    IService getLocalService(String service_name);
+
+    /**
+     * @return an object representing a service from local peer.
+     * Service object should implement given interface.
+     * Return null if implementation of the interface is not available.
+     */
+    <V extends IService> V getLocalService(Class<V> service_interface);
+
+    /**
+     * @return collection of services available on remote peer.
+     */
+    Collection<String> getRemoteServices();
+
+    /**
+     * Get a proxy for remote service.
+     * @param service_name - remote service name
+     * @return an object (proxy) representing a service from remote peer.
+     * Return null if the service is not available.
+     * Return an instance of GenericProxy if 'service_name' is not a standard TCF service.
+     */
+    IService getRemoteService(String service_name);
+
+    /**
+     * Get a proxy for remote service.
+     * @param service_interface - service interface class
+     * @return an object (proxy) representing a service from remote peer,
+     * which implements given interface.
+     * Return null if implementation of the interface is not available.
+     */
+    <V extends IService> V getRemoteService(Class<V> service_interface);
+    
+    /**
+     * Install a service proxy object on this channel.
+     * This method can be called only from channel open call-back.
+     * It allows a client to extend TCF by adding proxy objects for non-standard services.
+     * Client, wishing to become service proxy provider, should register itself
+     * using either Protocol.addChannelOpenListener() or IChannel.addChannelListener().
+     * It is not allowed to install more then one proxy for a given service interface on
+     * a particular channel.
+     * @param service_interface - service interface class
+     * @param service_proxy - service proxy object    
+     */
+    <V extends IService> void setServiceProxy(Class<V> service_interface, IService service_proxy);
+    
+    /**
+     * Close communication channel.
+     */
+    void close();
+
+    /**
+     * Close channel in case of communication error.
+     * @param error - cause of channel termination
+     */
+    void terminate(Throwable error);
+    
+    /**
+     * Redirect this channel to given peer using this channel remote peer locator service as a proxy.
+     * @param peer_id - peer that will become new remote communication endpoint of this channel
+     */
+    void redirect(String peer_id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IErrorReport.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+import java.util.Map;
+
+/**
+ * This interface defines TCF standard format of error reports.
+ * 
+ * Exception objects can implement this interface to make error report details
+ * available for clients.
+ * 
+ * Usage example:
+ * 
+ * Exception x = ...
+ * if (x instanceof IErrorReport) {
+ *      int error_code = ((IErrorReport)x).getErrorCode();
+ * ...
+ * 
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IErrorReport {
+
+    /** Error report attribute names */
+    public static final String
+        ERROR_CODE = "Code",            // integer
+        ERROR_TIME = "Time",            // integer
+        ERROR_SERVICE = "Service",      // string
+        ERROR_FORMAT = "Format",        // string
+        ERROR_PARAMS = "Params",        // array
+        ERROR_SEVERITY = "Severity",    // integer
+        ERROR_ALT_CODE = "AltCode",     // integer
+        ERROR_ALT_ORG = "AltOrg",       // string
+        ERROR_CAUSED_BY = "CausedBy";   // object
+    
+    /** Error severity codes */
+    public static final int
+        SEVERITY_ERROR = 0,
+        SEVERITY_WARNING = 1,
+        SEVERITY_FATAL = 2;
+    
+    /** Error code ranges */
+    public static final int
+        /** Standard TCF code range */
+        CODE_STD_MIN = 0,
+        CODE_STD_MAX = 0xffff,
+        
+        /** Service specific codes. Decoding requires service ID. */
+        CODE_SERVICE_SPECIFIC_MIN = 0x10000,
+        CODE_SERVICE_SPECIFIC_MAX = 0x1ffff,
+        
+        /** Reserved codes - will never be used by the TCF standard */
+        CODE_RESERVED_MIN = 0x20000,
+        CODE_RESERVED_MAX = 0x2ffff;
+    
+    /** Standard TCF error codes */ 
+    public static final int
+        TCF_ERROR_OTHER               = 1,
+        TCF_ERROR_JSON_SYNTAX         = 2,
+        TCF_ERROR_PROTOCOL            = 3,
+        TCF_ERROR_BUFFER_OVERFLOW     = 4,
+        TCF_ERROR_CHANNEL_CLOSED      = 5,
+        TCF_ERROR_COMMAND_CANCELLED   = 6,
+        TCF_ERROR_UNKNOWN_PEER        = 7,
+        TCF_ERROR_BASE64              = 8,
+        TCF_ERROR_EOF                 = 9,
+        TCF_ERROR_ALREADY_STOPPED     = 10,
+        TCF_ERROR_ALREADY_EXITED      = 11,
+        TCF_ERROR_ALREADY_RUNNING     = 12,
+        TCF_ERROR_ALREADY_ATTACHED    = 13,
+        TCF_ERROR_IS_RUNNING          = 14,
+        TCF_ERROR_INV_DATA_SIZE       = 15,
+        TCF_ERROR_INV_CONTEXT         = 16,
+        TCF_ERROR_INV_ADDRESS         = 17,
+        TCF_ERROR_INV_EXPRESSION      = 18,
+        TCF_ERROR_INV_FORMAT          = 19,
+        TCF_ERROR_INV_NUMBER          = 20,
+        TCF_ERROR_INV_DWARF           = 21,
+        TCF_ERROR_SYM_NOT_FOUND       = 22,
+        TCF_ERROR_UNSUPPORTED         = 23,
+        TCF_ERROR_INV_DATA_TYPE       = 24,
+        TCF_ERROR_INV_COMMAND         = 25;
+    
+    public int getErrorCode();
+    
+    public int getAltCode();
+    
+    public String getAltOrg();
+    
+    public Map<String,Object> getAttributes();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IEventQueue.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * Clients of stand-alone version the framework should implement this interface and call Protocol.setEventQueue.
+ * Eclipse based clients don't need to implement IEventQueue since the implementation is provide by TCF bundle activator.
+ * 
+ * Implementation should encapsulate a queue and asynchronous event dispatch machinery, which
+ * extracts events from the queue and dispatches them by calling event's run() method.
+ * The implementation is used by framework to queue and dispatch all events.
+ */
+public interface IEventQueue {
+
+    /**
+     * Causes <code>runnable</code> to have its <code>run</code>
+     * method called in the dispatch thread of this event queue.
+     * Events are dispatched in same order as queued.
+     *
+     * @param runnable  the <code>Runnable</code> whose <code>run</code>
+     *                  method should be executed asynchronously.
+     */
+    void invokeLater(Runnable runnable);
+
+    /**
+     * Returns true if the calling thread is this event queue's dispatch thread.
+     * Use this call the ensure that a given task is being executed (or not being) on dispatch thread.
+     *
+     * @return true if running on the dispatch thread.
+     */
+    boolean isDispatchThread();
+
+    /**
+     * Get current level of queue congestion.
+     * 
+     * @return integer value in range –100..100, where –100 means no pending
+     *         messages (no traffic), 0 means optimal load, and positive numbers
+     *         indicate level of congestion.
+     */
+    int getCongestion();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/ILogger.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * Clients of stand-alone version the framework should implement this interface and call Protocol.setLogger.
+ * Eclipse based clients don't need to implement ILogger since the implementation is provide by TCF bundle activator.
+ */
+public interface ILogger {
+
+    /**
+     * Add an entry into a log.
+     * 
+     * This method can be invoked from any thread.
+     * 
+     * @param msg - log entry text. 
+     * @param x - a Java exception associated with the log entry or null.
+     */
+    void log(String msg, Throwable x);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IPeer.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+import java.util.Map;
+
+/**
+ * Both hosts and targets are represented by objects
+ * implementing IPeer interface. A peer can act as host or
+ * target depending on services it implements.
+ * List of currently known peers can be retrieved by
+ * calling ILocator.getPeers()
+ * 
+ * @noimplement This interface is not intended to be implemented by clients.
+ * Client can extends the abstract IPeer implementation: AbstractPeer.
+ */
+public interface IPeer {
+
+    /**
+     * Peer property names. Implementation can define additional properties.  
+     */
+    static final String
+        ATTR_ID = "ID",
+        ATTR_NAME = "Name",
+        ATTR_OS_NAME = "OSName",
+        ATTR_TRANSPORT_NAME = "TransportName",
+        ATTR_PROXY = "Proxy",
+        ATTR_IP_HOST = "Host",
+        ATTR_IP_ALIASES = "Aliases",
+        ATTR_IP_ADDRESSES = "Addresses",
+        ATTR_IP_PORT = "Port";
+
+
+    /**
+     * @return map of peer attributes
+     */
+    Map<String, String> getAttributes();
+
+    /**
+     * @return peer unique ID, same as getAttributes().get(ATTR_ID)
+     */
+    String getID();
+
+    /**
+     * @return peer name, same as getAttributes().get(ATTR_NAME)
+     */
+    String getName();
+
+    /**
+     * Same as getAttributes().get(ATTR_OS_NAME)
+     */
+    String getOSName();
+
+    /**
+     * Same as getAttributes().get(ATTR_TRANSPORT_NAME)
+     */
+    String getTransportName();
+
+    /**
+     * Open channel to communicate with this peer.
+     * Note: the channel is not fully open yet when this method returns.
+     * It’s state is IChannel.STATE_OPENNING.
+     * Protocol.Listener will be called when the channel will be opened or closed.
+     */
+    IChannel openChannel();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IService.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * Base interface for all service interfaces. A client can get list of available services
+ * by calling IChannel.getLocalServices() and IChannel.getRemoteServices().
+ * 
+ * Remote services are represented by a proxy objects that implement service interfaces by
+ * translating method calls to TCF messages and sending them to a remote peer.
+ * When communication channel is open, TCF automatically creates proxies for standard services.
+ * TCF clients can provides addition proxies for non-standard services by calling IChannel.setServiceProxy(). 
+ */
+
+public interface IService {
+
+    /**
+     * Get unique name of this service.
+     * @return service name.
+     */
+    String getName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IServiceProvider.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Anyware Technologies and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Anyware Technologies  - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * Clients can implement this interface if they want to provide implementation of a local service or
+ * remote service proxy.  
+ */
+public interface IServiceProvider {
+    
+    public IService[] getLocalService(IChannel channel);
+    
+    public IService getServiceProxy(IChannel channel, String service_name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IToken.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * IToken is created by the framework for each command sent to a remote peer.
+ * It is used to match results to commands and to cancel pending commands.
+ * 
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IToken {
+
+    /**
+     * Try to cancel a command associated with given token. A command can be
+     * canceled by this method only if it was not transmitted yet to remote peer
+     * for execution. Successfully canceled command does not produce any result
+     * messages.
+     * 
+     * @return true if successful.
+     */
+    boolean cancel();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/ITransportProvider.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+/**
+ * ITransportProvider represents communication protocol that can be used to open TCF communication channels.
+ * Examples of transports are: TCP/IP, RS-232, USB.
+ * 
+ * Client can implement this interface if they want to provide support for a transport that is not
+ * supported directly by the framework.
+ */
+public interface ITransportProvider {
+    
+    /**
+     * Return transport name. Same as used as peer attribute, @see IPeer.ATTR_TRANSPORT_NAME
+     * @return transport name.
+     */
+    String getName();
+
+    /**
+     * Open channel to communicate with this peer using this transport.
+     * Note: the channel can be not fully open yet when this method returns.
+     * It’s state can be IChannel.STATE_OPENNING.
+     * Protocol.Listener will be called when the channel will be opened or closed.
+     * @param peer - a IPeer object that describes remote end-point of the channel. 
+     * @return TCF communication channel.
+     */
+    IChannel openChannel(IPeer peer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,688 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.Base64;
+
+
+/**
+ * JSON is TCF preferred marshaling. This class implements generation and parsing of JSON strings.
+ * The code is optimized for speed since it is a time-critical part of the framework.
+ *
+ * Reading of JSON produces data structure that consists of objects of these classes:
+ * Boolean, Number, String, Collection, Map.
+ * 
+ * Writing of JSON is supported for:
+ * Boolean, Number, String, char[], byte[], Object[], Collection, Map
+ * 
+ * Clients can enable writing support for objects of a other classes by
+ * registering ObjectWriter interface implementation.
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class JSON {
+    
+    /**
+     * Clients implement ObjectWriter interface when they want to enable marshaling of
+     * object classes that are not directly supported by JSON library.
+     */
+    public interface ObjectWriter {
+        void write(Object o) throws IOException;
+    }
+    
+    private static final Map<Class<?>,ObjectWriter> object_writers = new HashMap<Class<?>,ObjectWriter>(); 
+    
+    /** Wrapper class for binary byte blocs */
+    public final static class Binary {
+        public final byte[] bytes;
+        public final int offs;
+        public final int size;
+        
+        public Binary(byte[] bytes, int offs, int size) {
+            this.bytes = bytes;
+            this.offs = offs;
+            this.size = size;
+        }
+    }
+    
+    private static char[] tmp_buf = new char[0x1000];
+    private static byte[] tmp_bbf = new byte[0x1000];
+    private static int tmp_buf_pos;
+    private static boolean zero_copy;
+    private static Binary[] bin_buf = new Binary[0x10];
+    private static int bin_buf_pos;
+    
+    private static byte[] inp;
+    private static int inp_pos;
+    private static int cur_ch;
+    
+    // This buffer is used to create nice error reports 
+    private static final char[] err_buf = new char[100];
+    private static int err_buf_pos;
+    private static int err_buf_cnt;
+    
+    /**
+     * Add a handler for converting objects of a particular class into JSON.
+     * @param cls - a class
+     * @param writer - ObjectWriter implementation that provides generation of JSON for a given class.
+     */
+    public static void addObjectWriter(Class<?> cls, ObjectWriter writer) {
+        object_writers.put(cls, writer);
+    }
+
+    /**
+     * Write a character into JSON output buffer.
+     * Clients should not call this method directly, except from ObjectWriter implementation.
+     * @param ch
+     */
+    public static void write(char ch) {
+        if (tmp_buf_pos >= tmp_buf.length) {
+            char[] tmp = new char[tmp_buf.length * 2];
+            System.arraycopy(tmp_buf, 0, tmp, 0, tmp_buf_pos);
+            tmp_buf = tmp;
+        }
+        tmp_buf[tmp_buf_pos++] = ch;
+    }
+    
+    /**
+     * Write a string into JSON output buffer.
+     * The string is written "as-is". Call writeObject() to convert a String into JSON string.
+     * Clients should not call this method directly, except from ObjectWriter implementation.
+     * @param s - a string
+     */
+    public static void write(String s) {
+        int l = s.length();
+        for (int i = 0; i < l; i++) {
+            char ch = s.charAt(i);
+            if (tmp_buf_pos >= tmp_buf.length) write(ch);
+            else tmp_buf[tmp_buf_pos++] = ch;
+        }
+    }
+    
+    /**
+     * Write a non-negative integer number into JSON output buffer.
+     * Clients should not call this method directly, except from ObjectWriter implementation.
+     * @param n - a number
+     */
+    public static void writeUInt(int n) {
+        assert n >= 0;
+        if (n >= 10) writeUInt(n / 10);
+        write((char)('0' + n % 10));
+    }
+    
+    private static int readUTF8Char() {
+        if (inp_pos >= inp.length) return -1;
+        int ch = inp[inp_pos++];
+        if (ch < 0) {
+            if ((ch & 0xe0) == 0xc0) {
+                ch = (ch & 0x1f) << 6;
+                ch |= inp[inp_pos++] & 0x3f;
+            }
+            else if ((ch & 0xf0) == 0xe0) {
+                ch = (ch & 0x0f) << 12;
+                ch |= (inp[inp_pos++] & 0x3f) << 6;
+                ch |= inp[inp_pos++] & 0x3f;
+            }
+            else if ((ch & 0xf0) == 0xf0) {
+                ch = (ch & 0x0f) << 18;
+                ch |= (inp[inp_pos++] & 0x3f) << 12;
+                ch |= (inp[inp_pos++] & 0x3f) << 6;
+                ch |= inp[inp_pos++] & 0x3f;
+            }
+        }
+        return ch;
+    }
+
+    private static void read() throws IOException {
+        cur_ch = readUTF8Char();
+        err_buf[err_buf_pos++] = (char)cur_ch;
+        if (err_buf_pos >= err_buf.length) {
+            err_buf_pos = 0;
+            err_buf_cnt++;
+        }
+    }
+    
+    private static void error() throws IOException {
+        error("syntax error");
+    }
+
+    private static void error(String msg) throws IOException {
+        StringBuffer bf = new StringBuffer();
+        bf.append("JSON " + msg + ":");
+        int cnt = 0;
+        boolean nl = true;
+        for (int i = 0;; i++) {
+            char ch = 0;
+            if (err_buf_cnt == 0 && i < err_buf_pos) {
+                ch = err_buf[i];
+            }
+            else if (err_buf_cnt > 0 && i < err_buf.length) {
+                ch = err_buf[(err_buf_pos + i) % err_buf.length];
+            }
+            else {
+                int n = readUTF8Char();
+                if (n < 0) break;
+                ch = (char)n;
+            }
+            if (nl) {
+                bf.append("\n ");
+                if (err_buf_cnt == 0) bf.append(cnt);
+                else bf.append('*');
+                bf.append(": ");
+                if (cnt == 0 && err_buf_cnt > 0) bf.append("...");
+                nl = false;
+            }
+            if (ch == 0) {
+                cnt++;
+                nl = true;
+                continue;
+            }
+            bf.append(ch);
+        }
+        throw new IOException(bf.toString());
+    }
+
+    private static int readHexDigit() throws IOException {
+        int n = 0;
+        if (cur_ch >= '0' && cur_ch <= '9') n = cur_ch - '0';
+        else if (cur_ch >= 'A' && cur_ch <= 'F') n = cur_ch - 'A' + 10;
+        else if (cur_ch >= 'a' && cur_ch <= 'f') n = cur_ch - 'a' + 10;
+        else error();
+        read();
+        return n;
+    }
+    
+    private static Object readFloat(boolean sign, BigInteger val) throws IOException {
+        int scale = 0;
+        int fraction = 0;
+        if (cur_ch == '.') {
+            read();
+            while (cur_ch >= '0' && cur_ch <= '9') {
+                val = val.multiply(BigInteger.valueOf(10));
+                val = val.add(BigInteger.valueOf(cur_ch - '0'));
+                fraction++;
+                read();
+            }
+        }
+        if (cur_ch == 'E' || cur_ch == 'e') {
+            read();
+            boolean neg = cur_ch == '-';
+            if (neg || cur_ch == '+') read();
+            while (cur_ch >= '0' && cur_ch <= '9') {
+                scale = scale * 10 + cur_ch - '0';
+                read();
+            }
+            if (neg) scale = -scale;
+        }
+        if (sign) val = val.negate();
+        return new BigDecimal(val, fraction - scale);
+    }
+    
+    private static Object readNestedObject() throws IOException {
+        switch (cur_ch) {
+        case '(':
+            read();
+            int len = 0;
+            while (cur_ch >= '0' && cur_ch <= '9') {
+                len = len * 10 + (cur_ch - '0');
+                read();
+            }
+            if (cur_ch != ')') error();
+            byte[] res = new byte[len];
+            System.arraycopy(inp, inp_pos, res, 0, len);
+            inp_pos += len;
+            read();
+            return res;
+        case '"':
+            read();
+            tmp_buf_pos = 0;
+            for (;;) {
+                if (cur_ch <= 0) error();
+                if (cur_ch == '"') break;
+                if (cur_ch == '\\') {
+                    read();
+                    if (cur_ch <= 0) error();
+                    switch (cur_ch) {
+                    case '"':
+                    case '\\':
+                    case '/':
+                        break;
+                    case 'b':
+                        cur_ch = '\b';
+                        break;
+                    case 'f':
+                        cur_ch = '\f';
+                        break;
+                    case 'n':
+                        cur_ch = '\n';
+                        break;
+                    case 'r':
+                        cur_ch = '\r';
+                        break;
+                    case 't':
+                        cur_ch = '\t';
+                        break;
+                    case 'u':
+                        read();
+                        int n = 0;
+                        n |= readHexDigit() << 12;
+                        n |= readHexDigit() << 8;
+                        n |= readHexDigit() << 4;
+                        n |= readHexDigit();
+                        write((char)n);
+                        continue;
+                    default:
+                        error();
+                        break;
+                    }
+                }
+                if (tmp_buf_pos >= tmp_buf.length) {
+                    write((char)cur_ch);
+                }
+                else {
+                    tmp_buf[tmp_buf_pos++] = (char)cur_ch;
+                }
+                read();
+            }
+            read();
+            return new String(tmp_buf, 0, tmp_buf_pos);
+        case '[':
+            List<Object> l = new ArrayList<Object>();
+            read();
+            if (cur_ch <= 0) error();
+            if (cur_ch != ']') {
+                for (;;) {
+                    l.add(readNestedObject());
+                    if (cur_ch == ']') break;
+                    if (cur_ch != ',') error();
+                    read();
+                }
+            }
+            read();
+            return Collections.unmodifiableList(l);
+        case '{':
+            Map<String,Object> m = new HashMap<String,Object>();
+            read();
+            if (cur_ch <= 0) error();
+            if (cur_ch != '}') {
+                for (;;) {
+                    String key = (String)readNestedObject();
+                    if (cur_ch != ':') error();
+                    read();
+                    Object val = readNestedObject();
+                    m.put(key, val);
+                    if (cur_ch == '}') break;
+                    if (cur_ch != ',') error();
+                    read();
+                }
+            }
+            read();
+            return Collections.unmodifiableMap(m);
+        case 'n':
+            read();
+            if (cur_ch != 'u') error();
+            read();
+            if (cur_ch != 'l') error();
+            read();
+            if (cur_ch != 'l') error();
+            read();
+            return null;
+        case 'f':
+            read();
+            if (cur_ch != 'a') error();
+            read();
+            if (cur_ch != 'l') error();
+            read();
+            if (cur_ch != 's') error();
+            read();
+            if (cur_ch != 'e') error();
+            read();
+            return Boolean.FALSE;
+        case 't':
+            read();
+            if (cur_ch != 'r') error();
+            read();
+            if (cur_ch != 'u') error();
+            read();
+            if (cur_ch != 'e') error();
+            read();
+            return Boolean.TRUE;
+        default:
+            boolean neg = cur_ch == '-';
+            if (neg) read();
+            if (cur_ch >= '0' && cur_ch <= '9') {
+                int v = 0;
+                while (v <= 0x7fffffff / 10 - 1) {
+                    v = v * 10 + (cur_ch - '0');
+                    read();
+                    if (cur_ch < '0' || cur_ch > '9') {
+                        if (cur_ch == '.' || cur_ch == 'E' || cur_ch == 'e') {
+                            return readFloat(neg, BigInteger.valueOf(v));
+                        }
+                        if (neg) v = -v;
+                        return Integer.valueOf(v);
+                    }
+                }
+                long vl = v;
+                while (vl < 0x7fffffffffffffffl / 10 - 1) {
+                    vl = vl * 10 + (cur_ch - '0');
+                    read();
+                    if (cur_ch < '0' || cur_ch > '9') {
+                        if (cur_ch == '.' || cur_ch == 'E' || cur_ch == 'e') {
+                            return readFloat(neg, BigInteger.valueOf(vl));
+                        }
+                        if (neg) vl = -vl;
+                        return Long.valueOf(vl);
+                    }
+                }
+                StringBuffer sb = new StringBuffer();
+                sb.append(vl);
+                while (true) {
+                    sb.append(cur_ch);
+                    read();
+                    if (cur_ch < '0' || cur_ch > '9') {
+                        BigInteger n = new BigInteger(sb.toString());
+                        if (cur_ch == '.' || cur_ch == 'E' || cur_ch == 'e') {
+                            return readFloat(neg, n);
+                        }
+                        if (neg) n = n.negate();
+                        return n;
+                    }
+                }
+            }
+            error();
+            return null;
+        }
+    }
+
+    private static Object readObject() throws IOException {
+        Object o = readNestedObject();
+        if (cur_ch >= 0) error();
+        return o;
+    }
+
+    private static Object[] readSequence() throws IOException {
+        List<Object> l = new ArrayList<Object>();
+        while (cur_ch >= 0) {
+            if (cur_ch == 0) l.add(null);
+            else l.add(readNestedObject());
+            if (cur_ch != 0) error("missing \\0 terminator");
+            read();
+        }
+        return l.toArray();
+    }
+    
+    /**
+     * Write an object into JSON output buffer.
+     * Clients should not call this method directly, except from ObjectWriter implementation.
+     * @param o - an object to write
+     */
+    @SuppressWarnings("unchecked")
+    public static void writeObject(Object o) throws IOException {
+        if (o == null) {
+            write("null");
+        }
+        else if (o instanceof Boolean) {
+            write(o.toString());
+        }
+        else if (o instanceof Number) {
+            write(o.toString());
+        }
+        else if (o instanceof String) {
+            String s = (String)o;
+            char[] arr = new char[s.length()];
+            s.getChars(0, arr.length, arr, 0);
+            writeObject(arr);
+        }
+        else if (o instanceof char[]) {
+            char[] s = (char[])o;
+            write('"');
+            int l = s.length;
+            for (int i = 0; i < l; i++) {
+                char ch = s[i];
+                switch (ch) {
+                case 0:
+                    write("\\u0000");
+                    break;
+                case 1:
+                    write("\\u0001");
+                    break;
+                case '\r':
+                    write("\\r");
+                    break;
+                case '\n':
+                    write("\\n");
+                    break;
+                case '\t':
+                    write("\\t");
+                    break;
+                case '\b':
+                    write("\\b");
+                    break;
+                case '\f':
+                    write("\\f");
+                    break;
+                case '"':
+                case '\\':
+                    write('\\');
+                default:
+                    if (tmp_buf_pos >= tmp_buf.length) write(ch);
+                    else tmp_buf[tmp_buf_pos++] = ch;
+                }
+            }
+            write('"');
+        }
+        else if (o instanceof Binary) {
+            Binary b = (Binary)o;
+            if (zero_copy) {
+                write('(');
+                write(Integer.toString(b.size));
+                write(')');
+                write((char)1);
+                bin_buf[bin_buf_pos++] = b;
+            }
+            else {
+                writeObject(Base64.toBase64(b.bytes, b.offs, b.size));
+            }
+        }
+        else if (o instanceof byte[]) {
+            write('[');
+            byte[] arr = (byte[])o;
+            boolean comma = false;
+            for (int i = 0; i < arr.length; i++) {
+                if (comma) write(',');
+                writeUInt(arr[i] & 0xff);
+                comma = true;
+            }
+            write(']');
+        }
+        else if (o instanceof Object[]) {
+            write('[');
+            Object[] arr = (Object[])o;
+            boolean comma = false;
+            for (int i = 0; i < arr.length; i++) {
+                if (comma) write(',');
+                writeObject(arr[i]);
+                comma = true;
+            }
+            write(']');
+        }
+        else if (o instanceof Collection) {
+            write('[');
+            boolean comma = false;
+            for (Iterator<Object> i = ((Collection<Object>)o).iterator(); i.hasNext();) {
+                if (comma) write(',');
+                writeObject(i.next());
+                comma = true;
+            }
+            write(']');
+        }
+        else if (o instanceof Map) {
+            Map<String,Object> map = (Map<String,Object>)o;
+            write('{');
+            boolean comma = false;
+            for (Iterator<Map.Entry<String,Object>> i = map.entrySet().iterator(); i.hasNext();) {
+                if (comma) write(',');
+                Map.Entry<String,Object> e = i.next();
+                writeObject(e.getKey());
+                write(':');
+                writeObject(e.getValue());
+                comma = true;
+            }
+            write('}');
+        }
+        else {
+            ObjectWriter writer = object_writers.get(o.getClass());
+            if (writer != null) {
+                writer.write(o);
+            }
+            else {
+                throw new IOException("JSON: unsupported object type");
+            }
+        }
+    }
+
+    private static byte[] toBytes() {
+        int inp_pos = 0;
+        int out_pos = 0;
+        int blc_pos = 0;
+        while (inp_pos < tmp_buf_pos) {
+            if (out_pos > tmp_bbf.length - 4) {
+                byte[] tmp = new byte[tmp_bbf.length * 2];
+                System.arraycopy(tmp_bbf, 0, tmp, 0, out_pos);
+                tmp_bbf = tmp;
+            }
+            int ch = tmp_buf[inp_pos++];
+            if (ch == 1) {
+                Binary b = bin_buf[blc_pos++];
+                while (out_pos > tmp_bbf.length - b.size) {
+                    byte[] tmp = new byte[tmp_bbf.length * 2];
+                    System.arraycopy(tmp_bbf, 0, tmp, 0, out_pos);
+                    tmp_bbf = tmp;
+                }
+                System.arraycopy(b.bytes, b.offs, tmp_bbf, out_pos, b.size);
+                out_pos += b.size;
+            }
+            else if (ch < 0x80) {
+                tmp_bbf[out_pos++] = (byte)ch; 
+            }
+            else if (ch < 0x800) {
+                tmp_bbf[out_pos++] = (byte)((ch >> 6) | 0xc0); 
+                tmp_bbf[out_pos++] = (byte)(ch & 0x3f | 0x80); 
+            }
+            else if (ch < 0x10000) {
+                tmp_bbf[out_pos++] = (byte)((ch >> 12) | 0xe0); 
+                tmp_bbf[out_pos++] = (byte)((ch >> 6) & 0x3f | 0x80); 
+                tmp_bbf[out_pos++] = (byte)(ch & 0x3f | 0x80); 
+            }
+            else {
+                tmp_bbf[out_pos++] = (byte)((ch >> 18) | 0xf0); 
+                tmp_bbf[out_pos++] = (byte)((ch >> 12) & 0x3f | 0x80); 
+                tmp_bbf[out_pos++] = (byte)((ch >> 6) & 0x3f | 0x80); 
+                tmp_bbf[out_pos++] = (byte)(ch & 0x3f | 0x80); 
+            }
+        }
+        byte[] res = new byte[out_pos];
+        System.arraycopy(tmp_bbf, 0, res, 0, out_pos);
+        return res;
+    }
+
+    public static String toJSON(Object o) throws IOException {
+        assert Protocol.isDispatchThread();
+        tmp_buf_pos = 0;
+        bin_buf_pos = 0;
+        zero_copy = false;
+        writeObject(o);
+        return new String(tmp_buf, 0, tmp_buf_pos);
+    }
+
+    public static byte[] toJASONBytes(Object o) throws IOException {
+        assert Protocol.isDispatchThread();
+        tmp_buf_pos = 0;
+        bin_buf_pos = 0;
+        zero_copy = false;
+        writeObject(o);
+        return toBytes();
+    }
+
+    public static byte[] toJSONSequence(Object[] o) throws IOException {
+        assert Protocol.isDispatchThread();
+        if (o == null || o.length == 0) return null;
+        tmp_buf_pos = 0;
+        bin_buf_pos = 0;
+        zero_copy = false;
+        for (int i = 0; i < o.length; i++) {
+            writeObject(o[i]);
+            write((char)0);
+        }
+        return toBytes();
+    }
+
+    public static byte[] toJSONSequence(Object[] o, boolean zero_copy) throws IOException {
+        assert Protocol.isDispatchThread();
+        if (o == null || o.length == 0) return null;
+        tmp_buf_pos = 0;
+        bin_buf_pos = 0;
+        JSON.zero_copy = zero_copy;
+        for (int i = 0; i < o.length; i++) {
+            writeObject(o[i]);
+            write((char)0);
+        }
+        return toBytes();
+    }
+
+    public static Object parseOne(byte[] b) throws IOException {
+        assert Protocol.isDispatchThread();
+        if (b.length == 0) return null;
+        inp = b;
+        inp_pos = 0;
+        err_buf_pos = 0;
+        err_buf_cnt = 0;
+        read();
+        return readObject();
+    }
+
+    public static Object[] parseSequence(byte[] b) throws IOException {
+        assert Protocol.isDispatchThread();
+        inp = b;
+        inp_pos = 0;
+        err_buf_pos = 0;
+        err_buf_cnt = 0;
+        read();
+        return readSequence();
+    }
+    
+    public static byte[] toByteArray(Object o) {
+        if (o == null) return null;
+        if (o instanceof byte[]) return (byte[])o;
+        if (o instanceof char[]) return Base64.toByteArray((char[])o);
+        if (o instanceof String) return Base64.toByteArray(((String)o).toCharArray());
+        throw new Error();
+    }
+    
+    public static void toByteArray(byte[] buf, int offs, int size, Object o) {
+        if (o instanceof char[]) Base64.toByteArray(buf, offs, size, (char[])o);
+        else if (o instanceof String) Base64.toByteArray(buf, offs, size, ((String)o).toCharArray());
+        else if (o != null) System.arraycopy(toByteArray(o), 0, buf, offs, size);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/Protocol.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.protocol;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+
+import org.eclipse.tm.internal.tcf.core.LocalPeer;
+import org.eclipse.tm.internal.tcf.core.ServiceManager;
+import org.eclipse.tm.internal.tcf.core.TransportManager;
+import org.eclipse.tm.internal.tcf.services.local.LocatorService;
+import org.eclipse.tm.tcf.services.ILocator;
+
+
+/**
+ * Class Protocol provides static methods to access Target Communication Framework root objects:
+ * 1. the framework event queue and dispatch thread;
+ * 2. local instance of Locator service, which maintains a list of available targets;
+ * 3. list of open communication channels.
+ * 
+ * It also provides utility methods for posting asynchronous events,
+ * including delayed events (timers).
+ * 
+ * Before TCF can be used, it should be given an object implementing IEventQueue interface:
+ * @see #setEventQueue
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Protocol {
+
+    private static IEventQueue event_queue;
+    private static ILogger logger;
+    private static final TreeSet<Timer> timer_queue = new TreeSet<Timer>();
+    private static int timer_cnt;
+    
+    private static class Timer implements Comparable<Timer>{
+        final int id;
+        final long time;
+        final Runnable run;
+
+        Timer(long time, Runnable run) {
+            this.id = timer_cnt++;
+            this.time = time;
+            this.run = run;
+        }
+
+        public int compareTo(Timer x) {
+            if (x == this) return 0;
+            if (time < x.time) return -1;
+            if (time > x.time) return +1;
+            if (id < x.id) return -1;
+            if (id > x.id) return +1;
+            assert false;
+            return 0;
+        }
+    }
+
+    private static final Thread timer_dispatcher = new Thread() {
+        public void run() {
+            try {
+                synchronized (timer_queue) {
+                    while (true) {
+                        if (timer_queue.isEmpty()) {
+                            timer_queue.wait();
+                        }
+                        else {
+                            long time = System.currentTimeMillis();
+                            Timer t = timer_queue.first();
+                            if (t.time > time) {
+                                timer_queue.wait(t.time - time);
+                            }
+                            else {
+                                timer_queue.remove(t);
+                                invokeLater(t.run);
+                            }
+                        }
+                    }
+                }
+            }
+            catch (IllegalStateException x) {
+                // Dispatch is shut down, exit this thread
+            }
+            catch (Throwable x) {
+                log("Exception in TCF dispatch loop", x);
+            }
+        }
+    };
+
+    private static final ArrayList<CongestionMonitor> congestion_monitors = new ArrayList<CongestionMonitor>();
+
+    /**
+     * Before TCF can be used, it should be given an object implementing IEventQueue interface.
+     * The implementation maintains a queue of objects implementing Runnable interface and
+     * executes <code>run</code> methods of that objects in a sequence by a single thread.
+     * The thread in referred as TCF event dispatch thread. Objects in the queue are called TCF events.
+     * Executing <code>run</code> method of an event is also called dispatching of the event.
+     * 
+     * Only few methods in TCF APIs are thread safe - can be invoked from any thread.
+     * If a method description does not say "can be invoked from any thread" explicitly -  
+     * the method must be invoked from TCF event dispatch thread. All TCF listeners are
+     * invoked from the dispatch thread.
+     * 
+     * @param event_queue - IEventQueue implementation.
+     */
+    public static void setEventQueue(IEventQueue event_queue) {
+        assert Protocol.event_queue == null;
+        Protocol.event_queue = event_queue;
+        event_queue.invokeLater(new Runnable() {
+
+            public void run() {
+                new LocatorService();
+                new LocalPeer();
+            }
+        });
+        timer_dispatcher.setName("TCF Timer Dispatcher");
+        timer_dispatcher.setDaemon(true);
+        timer_dispatcher.start();
+    }
+
+    /**
+     * @return instance of IEventQueue that is used for TCF events.
+     */
+    public static IEventQueue getEventQueue() {
+        return event_queue;
+    }
+
+    /**
+     * Returns true if the calling thread is TCF event dispatch thread.
+     * Use this call the ensure that a given task is being executed (or not being)
+     * on dispatch thread.
+     *
+     * @return true if running on the dispatch thread.
+     */
+    public static boolean isDispatchThread() {
+        return event_queue != null && event_queue.isDispatchThread();
+    }
+
+    /**
+     * Causes <code>runnable</code> event to have its <code>run</code>
+     * method called in the dispatch thread of the framework.
+     * Events are dispatched in same order as queued.
+     * If invokeLater is called from the dispatching thread
+     * the <i>runnable.run()</i> will still be deferred until
+     * all pending events have been processed.
+     *
+     * This method can be invoked from any thread.
+     *
+     * @param runnable  the <code>Runnable</code> whose <code>run</code>
+     *                  method should be executed asynchronously.
+     */
+    public static void invokeLater(Runnable runnable) {
+        event_queue.invokeLater(runnable);
+    }
+
+    /**
+     * Causes <code>runnable</code> event to have its <code>run</code>
+     * method called in the dispatch thread of the framework.
+     * The event is dispatched after given delay.
+     *
+     * This method can be invoked from any thread.
+     *
+     * @param delay     milliseconds to delay event dispatch.
+     *                  If delay <= 0 the event is posted into the
+     *                  "ready" queue without delay.
+     * @param runnable  the <code>Runnable</code> whose <code>run</code>
+     *                  method should be executed asynchronously.
+     */
+    public static void invokeLater(long delay, Runnable runnable) {
+        if (delay <= 0) {
+            event_queue.invokeLater(runnable);
+        }
+        else {
+            synchronized (timer_queue) {
+                timer_queue.add(new Timer(System.currentTimeMillis() + delay, runnable));
+                timer_queue.notify();
+            }
+        }
+    }
+    
+    /**
+     * Causes <code>runnable</code> to have its <code>run</code>
+     * method called in the dispatch thread of the framework.
+     * Calling thread is suspended until the method is executed.
+     * If invokeAndWait is called from the dispatching thread
+     * the <i>runnable.run()</i> is executed immediately.
+     *
+     * This method can be invoked from any thread.
+     *
+     * @param runnable  the <code>Runnable</code> whose <code>run</code>
+     *                  method should be executed on dispatch thread.
+     */
+    public static void invokeAndWait(final Runnable runnable) {
+        if (event_queue.isDispatchThread()) {
+            runnable.run();
+        }
+        else {
+            Runnable r = new Runnable() {
+                public void run() {
+                    try {
+                        runnable.run();
+                    }
+                    finally {
+                        synchronized (this) {
+                            notify();
+                        }
+                    }
+                }
+            };
+            synchronized (r) {
+                event_queue.invokeLater(r);
+                try {
+                    r.wait();
+                }
+                catch (InterruptedException x) {
+                    throw new Error(x);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Set framework logger.
+     * By default Eclipse logger is used, or System.err if TCF is used stand-alone.
+     * 
+     * @param logger - an object implementing ILogger interface.
+     */
+    public static synchronized void setLogger(ILogger logger) {
+        Protocol.logger = logger;
+    }
+    
+    /**
+     * Logs the given message.
+     * @see #setLogger
+     * @param msg - log entry text
+     * @param x - a Java exception associated with the log entry or null.
+     */
+    public static synchronized void log(String msg, Throwable x) {
+        if (logger == null) {
+            System.err.println(msg);
+            if (x != null) x.printStackTrace();
+        }
+        else {
+            logger.log(msg, x);
+        }
+    }
+
+    /**
+     * Get instance of the framework locator service.
+     * The service can be used to discover available remote peers.
+     * 
+     * @return instance of ILocator.
+     */
+    public static ILocator getLocator() {
+        return LocatorService.getLocator();
+    }
+    
+    /**
+     * Return an array of all open channels.
+     * @return an array of IChannel
+     */
+    public static IChannel[] getOpenChannels() {
+        assert isDispatchThread();
+        return TransportManager.getOpenChannels();
+    }
+    
+    /**
+     * Interface to be implemented by clients willing to be notified when
+     * new TCF communication channel is opened.
+     * 
+     * The interface allows a client to get pointers to channel objects
+     * that were opened by somebody else. If a client open a channel itself, it already has
+     * the pointer and does not need Protocol.ChannelOpenListener. If a channel is created,
+     * for example, by remote peer connecting to the client, the only way to get the pointer
+     * is Protocol.ChannelOpenListener.
+     */
+    public interface ChannelOpenListener {
+        public void onChannelOpen(IChannel channel);
+    }
+    
+    /**
+     * Add a listener that will be notified when new channel is opened.
+     * @param listener
+     */
+    public static void addChannelOpenListener(ChannelOpenListener listener) {
+        assert isDispatchThread();
+        TransportManager.addChanelOpenListener(listener);
+    }
+
+    /**
+     * Remove channel opening listener.
+     * @param listener
+     */
+    public static void removeChannelOpenListener(ChannelOpenListener listener) {
+        assert isDispatchThread();
+        TransportManager.removeChanelOpenListener(listener);
+    }
+
+    /**
+     * Transmit TCF event message.
+     * The message is sent to all open communication channels – broadcasted.
+     */
+    public static void sendEvent(String service_name, String event_name, byte[] data) {
+        assert isDispatchThread();
+        TransportManager.sendEvent(service_name, event_name, data);
+    }
+    
+    /**
+     * Call back after all TCF messages sent by this host up to this moment are delivered
+     * to their intended target. This method is intended for synchronization of messages
+     * across multiple channels.
+     * 
+     * Note: Cross channel synchronization can reduce performance and throughput.
+     * Most clients don't need cross channel synchronization and should not call this method. 
+     *  
+     * @param done will be executed by dispatch thread after pending communication 
+     * messages are delivered to corresponding targets.
+     */
+    public static void sync(Runnable done) {
+        assert isDispatchThread();
+        TransportManager.sync(done);
+    }
+    
+    /**
+     * Clients implement CongestionMonitor interface to monitor usage of local resources,
+     * like, for example, display queue size - if the queue becomes too big, UI response time
+     * can become too high, or it can crash all together because of OutOfMemory errors.
+     * TCF flow control logic prevents such conditions by throttling traffic coming from remote peers.   
+     * Note: Local (in-bound traffic) congestion is detected by framework and reported to
+     * remote peer without client needed to be involved. Only clients willing to provide
+     * additional data about local congestion should implement CongestionMonitor and
+     * register it using Protocol.addCongestionMonitor().
+     */
+    public interface CongestionMonitor {
+        /**
+         * Get current level of client resource utilization. 
+         * @return integer value in range –100..100, where –100 means all resources are free,
+         *         0 means optimal load, and positive numbers indicate level of congestion.
+         */
+        int getCongestionLevel();
+    }
+    
+    /**
+     * Register a congestion monitor.
+     * @param monitor - client implementation of CongestionMonitor interface
+     */
+    public static void addCongestionMonitor(CongestionMonitor monitor) {
+        assert monitor != null;
+        assert isDispatchThread();
+        congestion_monitors.add(monitor);
+    }
+    
+    /**
+     * Unregister a congestion monitor.
+     * @param monitor - client implementation of CongestionMonitor interface
+     */
+    public static void removeCongestionMonitor(CongestionMonitor monitor) {
+        assert isDispatchThread();
+        congestion_monitors.remove(monitor);
+    }
+    
+    /**
+     * Get current level of local traffic congestion.
+     * 
+     * @return integer value in range –100..100, where –100 means no pending
+     *         messages (no traffic), 0 means optimal load, and positive numbers
+     *         indicate level of congestion.
+     */
+    public static int getCongestionLevel() {
+        assert isDispatchThread();
+        int level = -100;
+        for (CongestionMonitor m : congestion_monitors) {
+            int n = m.getCongestionLevel();
+            if (n > level) level = n;
+        }
+        if (event_queue != null) {
+            int n = event_queue.getCongestion();
+            if (n > level) level = n;
+        }
+        if (level > 100) level = 100;
+        return level;
+    }
+
+    /**
+     * Register s service provider. 
+     * @param provider - IServiceProvider implementation
+     */
+    public static void addServiceProvider(IServiceProvider provider){
+        ServiceManager.addServiceProvider(provider);
+    }
+    
+    /**
+     * Unregister s service provider. 
+     * @param provider - IServiceProvider implementation
+     */
+    public static void removeServiceProvider(IServiceProvider provider){
+        ServiceManager.removeServiceProvider(provider);
+    }
+
+    /**
+     * Register s transport provider. 
+     * @param provider - ITransportProvider implementation
+     */
+    public static void addTransportProvider(ITransportProvider provider){
+        assert isDispatchThread();
+        TransportManager.addTransportProvider(provider);
+    }
+    
+    /**
+     * Unregister s transport provider. 
+     * @param provider - ITransportProvider implementation
+     */
+    public static void removeTransportProvider(ITransportProvider provider){
+        assert isDispatchThread();
+        TransportManager.removeTransportProvider(provider);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IBreakpoints.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * Breakpoint is represented by unique identifier and set of properties.
+ * Breakpoint identifier (String id) needs to be unique across all hosts and targets.
+ * 
+ * Breakpoint properties (Map<String,Object>) is extendible collection of named attributes,
+ * which define breakpoint location and behavior. This module defines some common
+ * attribute names (see PROP_*), host tools and target agents may support additional attributes.
+ * 
+ * For each breakpoint a target agent maintains another extendible collection of named attributes:
+ * breakpoint status (Map<String,Object>, see STATUS_*). While breakpoint properties are
+ * persistent and represent user input, breakpoint status reflects dynamic target agent reports
+ * about breakpoint current state, like actual addresses where breakpoint is planted or planting errors.
+ */
+public interface IBreakpoints extends IService {
+
+    /**
+     * Service name.
+     */
+    static final String NAME = "Breakpoints";
+
+    /**
+     * Breakpoint property names.
+     */
+    static final String   
+        PROP_ID = "ID",                           // String
+        PROP_ENABLED = "Enabled",                 // Boolean
+        PROP_TYPE = "BreakpointType",             // String
+        PROP_CONTEXTNAMES = "ContextNames",       // Array
+        PROP_CONTEXTIDS = "ContextIds",           // Array
+        PROP_EXECUTABLEPATHS = "ExecPaths",       // Array
+        PROP_LOCATION = "Location",               // String
+        PROP_SIZE = "Size",                       // Number
+        PROP_ACCESSMODE = "AccessMode",           // Number
+        PROP_FILE = "File",                       // String
+        PROP_LINE = "Line",                       // Number
+        PROP_COLUMN = "Column",                   // Number
+        PROP_PATTERN = "MaskValue",               // Number
+        PROP_MASK = "Mask",                       // Number
+        PROP_STOP_GROUP = "StopGroup",            // Array
+        PROP_IGNORECOUNT = "IgnoreCount",         // Number
+        PROP_TIME = "Time",                       // Number
+        PROP_SCALE = "TimeScale",                 // String
+        PROP_UNITS = "TimeUnits",                 // String
+        PROP_CONDITION = "Condition",             // String
+        PROP_TEMPORARY = "Temporary";             // Boolean
+
+    /**
+     * BreakpointType values 
+     */
+    static final String
+        TYPE_RELATIVE = "Software",
+        TYPE_ABSOLUTE = "Hardware",
+        TYPE_AUTO = "Auto";
+
+    /** 
+     * AccessMode values 
+     */ 
+    static final int 
+        ACCESSMODE_READ    = 0x01,
+        ACCESSMODE_WRITE   = 0x02, 
+        ACCESSMODE_EXECUTE = 0x04,
+        ACCESSMODE_CHANGE  = 0x08;
+
+    /**
+     * TimeScale values 
+     */
+    static final String 
+        TIMESCALE_RELATIVE = "Relative",
+        TIMESCALE_ABSOLUTE = "Absolute";
+    
+    /**
+     * TimeUnits values 
+     */
+    static final String
+        TIMEUNIT_NSECS = "Nanoseconds",
+        TIMEUNIT_CYCLE_COUNT = "CycleCount",
+        TIMEUNIT_INSTRUCTION_COUNT = "InstructionCount";
+
+    /**
+     * Breakpoint status field names.
+     */
+    static final String
+        STATUS_INSTANCES = "Instances", // Array of Map<String,Object>
+        STATUS_ERROR = "Error",         // String
+        STATUS_FILE = "File",           // String
+        STATUS_LINE = "Line",           // Number
+        STATUS_COLUMN = "Column";       // Number
+    
+    /**
+     * Breakpoint instance field names.
+     */
+    static final String
+        INSTANCE_ERROR = "Error",       // String
+        INSTANCE_CONTEXT = "LocationContext", // String
+        INSTANCE_ADDRESS = "Address";   // Number
+    
+    /**
+     * Breakpoint service capabilities.
+     */
+    static final String
+        CAPABILITY_CONTEXT_ID = "ID",                   // String
+        CAPABILITY_HAS_CHILDREN = "HasChildren",        // Boolean
+        CAPABILITY_ADDRESS = "Location",                // Boolean
+        CAPABILITY_CONDITION = "Condition",             // Boolean
+        CAPABILITY_FILE_LINE = "FileLine";              // Boolean
+
+    /**
+     * Call back interface for breakpoint service commands.
+     */
+    interface DoneCommand {
+        /**
+         * Called when command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneCommand(IToken token, Exception error);
+    }
+
+    /**
+     * Download breakpoints data to target agent.
+     * The command is intended to be used only to initialize target breakpoints table 
+     * when communication channel is open. After that, host should 
+     * notify target about (incremental) changes in breakpoint data by sending
+     * add, change and remove commands.
+     * 
+     * @param properties - array of breakpoints.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken set(Map<String,Object>[] properties, DoneCommand done);
+
+    /**
+     * Called when breakpoint is added into breakpoints table.
+     * @param properties - breakpoint properties.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken add(Map<String,Object> properties, DoneCommand done);
+
+    /**
+     * Called when breakpoint properties are changed.
+     * @param properties - breakpoint properties.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken change(Map<String,Object> properties, DoneCommand done);
+
+    /**
+     * Tell target to change (only) PROP_ENABLED breakpoint property to 'true'.
+     * @param ids - array of enabled breakpoint identifiers.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken enable(String[] ids, DoneCommand done);
+
+    /**
+     * Tell target to change (only) PROP_ENABLED breakpoint property to 'false'.
+     * @param ids - array of disabled breakpoint identifiers.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken disable(String[] ids, DoneCommand done);
+
+    /**
+     * Tell target to remove breakpoints.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken remove(String[] ids, DoneCommand done);
+    
+    /**
+     * Upload IDs of breakpoints known to target agent.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken getIDs(DoneGetIDs done);
+
+    /**
+     * Call back interface for 'getIDs' command.
+     */
+    interface DoneGetIDs {
+        /**
+         * Called when 'getIDs' command is done. 
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param ids - IDs of breakpoints known to target agent.
+         */
+        void doneGetIDs(IToken token, Exception error, String[] ids);
+    }
+
+    /**
+     * Upload properties of given breakpoint from target agent breakpoint table.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     */
+    IToken getProperties(String id, DoneGetProperties done);
+
+    /**
+     * Call back interface for 'getProperties' command.
+     */
+    interface DoneGetProperties {
+        /**
+         * Called when 'getProperties' command is done. 
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param properties - properties of the breakpoint.
+         */
+        void doneGetProperties(IToken token, Exception error, Map<String,Object> properties);
+    }
+
+    /**
+     * Upload status of given breakpoint from target agent.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken getStatus(String id, DoneGetStatus done);
+
+    /**
+     * Call back interface for 'getStatus' command.
+     */
+    interface DoneGetStatus {
+        /**
+         * Called when 'getStatus' command is done. 
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param status - status of the breakpoint.
+         */
+        void doneGetStatus(IToken token, Exception error, Map<String,Object> status);
+    }
+
+    /**
+     * Report breakpoint service capabilities to clients so they
+     * can adjust to different implementations of the service.
+     * When called with a null ("") context ID the global capabilities are returned,
+     * otherwise context specific capabilities are returned.  A special capability
+     * property is used to indicate that all child contexts have the same
+     * capabilities.
+     * @param id - a context ID or null.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken getCapabilities(String id, DoneGetCapabilities done);
+
+    /**
+     * Call back interface for 'getCapabilities' command.
+     */
+    interface DoneGetCapabilities {
+        /**
+         * Called when 'getCapabilities' command is done. 
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param capabilities - breakpoints service capabilities description.
+         */
+        void doneGetCapabilities(IToken token, Exception error, Map<String,Object> capabilities);
+    }
+
+    /**
+     * Breakpoints service events listener.
+     * Note that contextAdded, contextChanged and contextRemoved events carry exactly same set
+     * of breakpoint properties that was sent by a client to a target. The purpose of these events is to
+     * let all clients know about breakpoints that were created by other clients.
+     */
+    interface BreakpointsListener {
+
+        /**
+         * Called when breakpoint status changes.
+         * @param id - unique breakpoint identifier.
+         * @param status - breakpoint status.
+         */
+        void breakpointStatusChanged(String id, Map<String,Object> status);
+
+        /**
+         * Called when a new breakpoints are added.
+         * @param bps - array of breakpoints.
+         */
+        void contextAdded(Map<String,Object>[] bps);
+
+        /**
+         * Called when breakpoint properties change.
+         * @param bps - array of breakpoints.
+         */
+        void contextChanged(Map<String,Object>[] bps);
+
+        /**
+         * Called when breakpoints are removed .
+         * @param ids - array of breakpoint IDs.
+         */
+        void contextRemoved(String[] ids);
+    }
+
+    /**
+     * Add breakpoints service event listener.
+     * @param listener - object that implements BreakpointsListener interface.
+     */
+    void addListener(BreakpointsListener listener);
+
+    /**
+     * Remove breakpoints service event listener.
+     * @param listener - object that implements BreakpointsListener interface.
+     */
+    void removeListener(BreakpointsListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IDiagnostics.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.math.BigDecimal;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+/**
+ * This is optional service that can be implemented by a peer. 
+ * If implemented, the service can be used for testing of the peer and
+ * communication channel functionality and reliability.
+ */
+
+public interface IDiagnostics extends IService {
+
+    static final String NAME = "Diagnostics";
+    
+    /**
+     * 'echo' command result returns same string that was given as command argument.
+     * The command is used to test communication channel ability to transmit arbitrary strings in
+     * both directions.  
+     * @param s - any string.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken echo(String s, DoneEcho done);
+    
+    /**
+     * Call back interface for 'echo' command.
+     */
+    interface DoneEcho {
+        /**
+         * Called when 'echo' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param s - same string as the command argument.
+         */
+        void doneEcho(IToken token, Throwable error, String s);
+    }
+
+    /**
+     * 'echoFP' command result returns same floating point number that was given as command argument.
+     * The command is used to test communication channel ability to transmit arbitrary floating point numbers in
+     * both directions.  
+     * @param n - any floating point number.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken echoFP(BigDecimal n, DoneEchoFP done);
+    
+    /**
+     * Call back interface for 'echoFP' command.
+     */
+    interface DoneEchoFP {
+        /**
+         * Called when 'echoFP' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param n - same number as the command argument.
+         */
+        void doneEchoFP(IToken token, Throwable error, BigDecimal n);
+    }
+
+    /**
+     * Get list of test names that are implemented by the service.
+     * Clients can request remote peer to run a test from the list.
+     * When started, a test performs a predefined set actions.
+     * Nature of test actions is uniquely identified by test name.
+     * Exact description of test actions is a contract between client and remote peer,
+     * and it is not part of Diagnostics service specifications.
+     * Clients should not attempt to run a test if they don't recognize the test name.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken getTestList(DoneGetTestList done);
+    
+    /**
+     * Call back interface for 'getTestList' command.
+     */
+    interface DoneGetTestList {
+        /**
+         * Called when 'getTestList' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param list - names of tests that are supported by the peer. 
+         */
+        void doneGetTestList(IToken token, Throwable error, String[] list);
+    }
+    
+    /**
+     * Run a test. When started, a test performs a predefined set actions.
+     * Nature of test actions is uniquely identified by test name.
+     * Running test usually has associated execution context ID.
+     * Depending on the test, the ID can be used with services RunControl and/or Processes services to control
+     * test execution, and to obtain test results.
+     * @param name - test name
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken runTest(String name, DoneRunTest done);
+    
+    /**
+     * Call back interface for 'runTest' command.
+     */
+    interface DoneRunTest {
+        /**
+         * Called when 'runTest' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param context_id - test execution contest ID.
+         */
+        void doneRunTest(IToken token, Throwable error, String context_id);
+    }
+
+    /**
+     * Cancel execution of a test.
+     * @param context_id - text execution context ID.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken cancelTest(String context_id, DoneCancelTest done);
+    
+    /**
+     * Call back interface for 'cancelTest' command.
+     */
+    interface DoneCancelTest {
+        /**
+         * Called when 'cancelTest' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneCancelTest(IToken token, Throwable error);
+    }
+    
+    /**
+     * Get information about a symbol in text execution context.
+     * @param context_id
+     * @param symbol_name
+     * @param done
+     * @return
+     */
+    IToken getSymbol(String context_id, String symbol_name, DoneGetSymbol done);
+    
+    /**
+     * Call back interface for 'getSymbol' command.
+     */
+    interface DoneGetSymbol {
+        /**
+         * Called when 'getSymbol' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param symbol
+         */
+        void doneGetSymbol(IToken token, Throwable error, ISymbol symbol);
+    }
+    
+    /**
+     * Interface to access result value of 'getSymbol' command.
+     */
+    interface ISymbol {
+        String getSectionName();
+        Number getValue();
+        boolean isUndef();
+        boolean isCommon();
+        boolean isGlobal();
+        boolean isLocal();
+        boolean isAbs();
+    }
+    
+    /**
+     * Create a pair of virtual streams, @see IStreams service.
+     * Remote ends of the streams are connected, so any data sent into 'inp' stream
+     * will become for available for reading from 'out' stream.
+     * The command is used for testing virtual streams.
+     * @param inp_buf_size - buffer size in bytes of the input stream.
+     * @param out_buf_size - buffer size in bytes of the output stream.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken createTestStreams(int inp_buf_size, int out_buf_size, DoneCreateTestStreams done);
+    
+    /**
+     * Call back interface for 'createTestStreams' command.
+     */
+    interface DoneCreateTestStreams {
+        
+        /**
+         * Called when 'createTestStreams' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param inp_id - the input stream ID.
+         * @param out_id - the output stream ID.
+         */
+        void doneCreateTestStreams(IToken token, Throwable error, String inp_id, String out_id);
+    }
+    
+    /**
+     * Dispose a virtual stream that was created by 'createTestStreams' command.
+     * @param id - the stream ID.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken disposeTestStream(String id, DoneDisposeTestStream done);
+    
+    /**
+     * Call back interface for 'disposeTestStream' command.
+     */
+    interface DoneDisposeTestStream {
+        
+        /**
+         * Called when 'createTestStreams' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneDisposeTestStream(IToken token, Throwable error);
+    }
+    
+    /**
+     * Send a command that is not implemented by peer.
+     * Used to test handling of 'N' messages by communication channel.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken not_implemented_command(DoneNotImplementedCommand done);
+    
+    interface DoneNotImplementedCommand {
+        
+        /**
+         * Called when 'not_implemented_command' command is done.
+         * @param token - command handle.
+         * @param error - error object.
+         */
+        void doneNotImplementedCommand(IToken token, Throwable error);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IExpressions.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+/**
+ * Expressions service allows TCF client to perform expression evaluation on remote target.
+ * The service can be used to retrieve or modify values of variables or any data structures in remote target memory.
+ */
+public interface IExpressions extends IService {
+
+    /**
+     * Service name.
+     */
+    static final String NAME = "Expressions";
+    
+    /**
+     * Expression object represent an expression that can be evaluated by remote target.
+     * It has a unique ID and contains all information necessary to compute a value.
+     * The object data usually includes:
+     *   1. process, thread or stack frame ID that should be used to resolve symbol names;
+     *   2. a script that can compute a value, like "x.y + z"  
+     */
+    interface Expression {
+        /**
+         * Get context ID.
+         * @return context ID.
+         */
+        String getID();
+        
+        /**
+         * Get parent context ID.
+         * @return parent context ID.
+         */
+        String getParentID();
+                
+        /**
+         * Get expression script language ID.
+         * @return language ID.
+         */
+        String getLanguage();
+        
+        /**
+         * Return expression string - the script part of the context.
+         * @return expression script string 
+         */
+        String getExpression();
+        
+        /**
+         * Get size of expression value in bits.
+         * Can be 0 if value size is even number of bytes, use getSize() in such case.
+         * @return size in bits.
+         */
+        int getBits();
+        
+        /**
+         * Get size in bytes. The size can include extra (unused) bits.
+         * This is "static" or "declared" size - as determined by expression type.
+         * @return size in bytes.
+         */
+        int getSize();
+        
+        /**
+         * Get expression type ID. Symbols service can be used to get type properties.
+         * This is "static" or "declared" type ID, actual type of a value can be different -
+         * if expression language supports dynamic typing. 
+         * @return type ID.
+         */
+        String getTypeID();
+        
+        /**
+         * Check if the expression can be assigned a new value.
+         * @return true if can assign.
+         */
+        boolean canAssign();
+        
+        /**
+         * Get complete map of context properties.
+         * @return map of context properties.
+         */
+        Map<String,Object> getProperties();
+    }
+
+    /**
+     * Expression context property names.
+     */
+    static final String
+        PROP_ID = "ID",
+        PROP_PARENT_ID = "ParentID",
+        PROP_LANGUAGE = "Language",
+        PROP_EXPRESSION = "Expression",
+        PROP_BITS = "Bits",
+        PROP_SIZE = "Size",
+        PROP_TYPE = "Type",
+        PROP_CAN_ASSIGN = "CanAssign";
+
+    /**
+     * Value represents result of expression evaluation.
+     * Note that same expression can be evaluated multiple times with different results.
+     */
+    interface Value {
+        
+        /**
+         * Get value type class.
+         * @see ISymbols.TypeClass
+         * @return
+         */
+        ISymbols.TypeClass getTypeClass();
+        
+        /**
+         * Get value type ID. Symbols service can be used to get type properties.
+         * @return type ID.
+         */
+        String getTypeID();
+
+        /**
+         * Get execution context ID (thread or process) that owns type symbol for this value.
+         * @return execution context ID.
+         */
+        String getExeContextID();
+
+        /**
+         * Check endianess of the values.
+         * Big endian means decreasing numeric significance with increasing byte number. 
+         * @return true if big endian.
+         */
+        boolean isBigEndian();
+        
+        /**
+         * Get value as array of bytes.
+         * @return value as array of bytes.
+         */
+        byte[] getValue();
+
+        /**
+         * Get complete map of value properties.
+         * @return map of value properties.
+         */
+        Map<String,Object> getProperties();
+    }
+
+    /**
+     * Expression value property names.
+     */
+    static final String
+        VAL_CLASS = "Class",
+        VAL_TYPE = "Type",
+        VAL_EXE_ID = "ExeID",
+        VAL_BIG_ENDIAN = "BigEndian";
+
+    /**
+     * Retrieve expression context info for given context ID.
+     * @see Expression
+     *   
+     * @param id – context ID. 
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context properties.
+         */
+        void doneGetContext(IToken token, Exception error, Expression context);
+    }
+
+    /**
+     * Retrieve children IDs for given parent ID.
+     * Meaning of the operation depends on parent kind:
+     * 1. expression with type of a struct, union, or class - fields; 
+     * 2. expression with type of an enumeration - enumerators;
+     * 3. expression with type of an array - array elements;
+     * 4. stack frame - function arguments and local variables;
+     * 5. thread - top stack frame function arguments and local variables;
+     * 6. process - global variables;
+     * 
+     * Children list does *not* include IDs of expressions that were created by clients
+     * using "create" command.
+     * 
+     * @param parent_context_id – parent context ID.
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * Create an expression context.
+     * The context should be disposed after use.
+     * @param parent_id - a context ID that can be used to resolve symbol names.
+     * @param language - language of expression script, null means default language
+     * @param expression - expression script
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken create(String parent_id, String language, String expression, DoneCreate done);
+
+    /**
+     * Client call back interface for create().
+     */
+    interface DoneCreate {
+        /**
+         * Called when context create context command is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context properties.
+         */
+        void doneCreate(IToken token, Exception error, Expression context);
+    }
+
+    /**
+     * Dispose an expression context that was created by create()
+     * @param id - the expression context ID
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken dispose(String id, DoneDispose done);
+    
+    /**
+     * Client call back interface for dispose().
+     */
+    interface DoneDispose {
+        /**
+         * Called when context dispose command is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         */
+        void doneDispose(IToken token, Exception error);
+    }
+
+    /**
+     * Evaluate value of an expression context.
+     * @param id - the expression context ID
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken evaluate(String id, DoneEvaluate done);
+    
+    /**
+     * Client call back interface for evaluate().
+     */
+    interface DoneEvaluate {
+        /**
+         * Called when context dispose command is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param value - expression evaluation result
+         */
+        void doneEvaluate(IToken token, Exception error, Value value);
+    }
+    
+    /**
+     * Assign a value to memory location determined by an expression.
+     * @param id - expression ID.
+     * @param value - value as an array of bytes.
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken assign(String id, byte[] value, DoneAssign done);
+    
+    /**
+     * Client call back interface for assign().
+     */
+    interface DoneAssign {
+        /**
+         * Called when assign command is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         */
+        void doneAssign(IToken token, Exception error);
+    }
+    
+    /**
+     * Add expressions service event listener.
+     * @param listener - event listener implementation.
+     */
+    void addListener(ExpressionsListener listener);
+
+    /**
+     * Remove expressions service event listener.
+     * @param listener - event listener implementation.
+     */
+    void removeListener(ExpressionsListener listener);
+
+    /**
+     * Registers event listener is notified when registers context hierarchy
+     * changes, and when a register is modified by the service commands. 
+     */
+    interface ExpressionsListener {
+
+        /**
+         * Called when expression value was changed and clients 
+         * need to update themselves. Clients, at least, should invalidate
+         * corresponding cached expression data.
+         * Not every change is notified - it is not possible,
+         * only those, which are not caused by normal execution of the debuggee.
+         * At least, changes caused by "assign" command should be notified.
+         * @param id - expression context ID.
+         */
+        void valueChanged(String id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IFileSystem.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,666 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * File System service provides file transfer (and more generally file
+ * system access) functionality in TCF. The service design is
+ * derived from SSH File Transfer Protocol specifications.
+ *  
+ *      Request Synchronization and Reordering
+ *
+ * The protocol and implementations MUST process requests relating to
+ * the same file in the order in which they are received.  In other
+ * words, if an application submits multiple requests to the server, the
+ * results in the responses will be the same as if it had sent the
+ * requests one at a time and waited for the response in each case.  For
+ * example, the server may process non-overlapping read/write requests
+ * to the same file in parallel, but overlapping reads and writes cannot
+ * be reordered or parallelized.  However, there are no ordering
+ * restrictions on the server for processing requests from two different
+ * file transfer connections.  The server may interleave and parallelize
+ * them at will.
+ *
+ * There are no restrictions on the order in which responses to
+ * outstanding requests are delivered to the client, except that the
+ * server must ensure fairness in the sense that processing of no
+ * request will be indefinitely delayed even if the client is sending
+ * other requests so that there are multiple outstanding requests all
+ * the time.
+ *
+ * There is no limit on the number of outstanding (non-acknowledged)
+ * requests that the client may send to the server.  In practice this is
+ * limited by the buffering available on the data stream and the queuing
+ * performed by the server.  If the server's queues are full, it should
+ * not read any more data from the stream, and flow control will prevent
+ * the client from sending more requests.
+ * 
+ *      File Names
+ *
+ * This protocol represents file names as strings.  File names are
+ * assumed to use the slash ('/') character as a directory separator.
+ *
+ * File names starting with a slash are "absolute", and are relative to
+ * the root of the file system.  Names starting with any other character
+ * are relative to the user's default directory (home directory). Client
+ * can use 'user()' command to retrieve current user home directory.
+ *
+ * Servers SHOULD interpret a path name component ".." as referring to
+ * the parent directory, and "." as referring to the current directory.
+ * If the server implementation limits access to certain parts of the
+ * file system, it must be extra careful in parsing file names when
+ * enforcing such restrictions.  There have been numerous reported
+ * security bugs where a ".." in a path name has allowed access outside
+ * the intended area.
+ *
+ * An empty path name is valid, and it refers to the user's default
+ * directory (usually the user's home directory).
+ *
+ * Otherwise, no syntax is defined for file names by this specification.
+ * Clients should not make any other assumptions; however, they can
+ * splice path name components returned by readdir() together
+ * using a slash ('/') as the separator, and that will work as expected.
+ */
+public interface IFileSystem extends IService {
+    
+    /**
+     * Service name.
+     */
+    static final String NAME = "FileSystem";
+
+    /**
+     * Flags to be used with open() method.
+     */
+    static final int 
+    
+        /**
+         * Open the file for reading.
+         */
+        TCF_O_READ              = 0x00000001,
+
+        /**
+         * Open the file for writing. If both this and TCF_O_READ are
+         * specified, the file is opened for both reading and writing.
+         */
+        TCF_O_WRITE             = 0x00000002,
+
+        /**
+         * Force all writes to append data at the end of the file.
+         */
+        TCF_O_APPEND            = 0x00000004, 
+
+        /**
+         * If this flag is specified, then a new file will be created if one
+         * does not already exist (if TCF_O_TRUNC is specified, the new file will
+         * be truncated to zero length if it previously exists).
+         */
+        TCF_O_CREAT             = 0x00000008,
+
+        /**
+         * Forces an existing file with the same name to be truncated to zero
+         * length when creating a file by specifying TCF_O_CREAT.
+         * TCF_O_CREAT MUST also be specified if this flag is used.
+         */
+        TCF_O_TRUNC             = 0x00000010,
+
+        /**
+         * Causes the request to fail if the named file already exists.
+         * TCF_O_CREAT MUST also be specified if this flag is used.
+         */
+        TCF_O_EXCL              = 0x00000020;
+
+    /**
+     * Flags to be used together with FileAttrs.
+     * The flags specify which of the fields are present.  Those fields
+     * for which the corresponding flag is not set are not present (not
+     * included in the message).
+     */
+    static final int
+        ATTR_SIZE               = 0x00000001,
+        ATTR_UIDGID             = 0x00000002,
+        ATTR_PERMISSIONS        = 0x00000004,
+        ATTR_ACMODTIME          = 0x00000008;
+
+    /**
+     * FileAttrs is used both when returning file attributes from
+     * the server and when sending file attributes to the server.  When
+     * sending it to the server, the flags field specifies which attributes
+     * are included, and the server will use default values for the
+     * remaining attributes (or will not modify the values of remaining
+     * attributes).  When receiving attributes from the server, the flags
+     * specify which attributes are included in the returned data.  The
+     * server normally returns all attributes it knows about.
+     */
+    final static class FileAttrs {
+        
+        /**
+         * The `flags' specify which of the fields are present.
+         */
+        public final int flags;
+        
+        /**
+         * The `size' field specifies the size of the file in bytes.
+         */
+        public final long size;
+        
+        /**
+         * The `uid' and `gid' fields contain numeric Unix-like user and group
+         * identifiers, respectively.
+         */
+        public final int uid;
+        public final int gid;
+        
+        /**
+         * The `permissions' field contains a bit mask of file permissions as
+         * defined by posix [1].
+         */
+        public final int permissions;
+        
+        /**
+         * The `atime' and `mtime' contain the access and modification times of
+         * the files, respectively. They are represented as milliseconds from
+         * midnight Jan 1, 1970 in UTC.
+         */
+        public final long atime;
+        public final long mtime;
+
+        /**
+         * Additional (non-standard) attributes.
+         */
+        public final Map<String,Object> attributes;
+        
+        public FileAttrs(int flags, long size, int uid, int gid,
+                int permissions, long atime, long mtime, Map<String,Object> attributes) {
+            this.flags = flags;
+            this.size = size;
+            this.uid = uid;
+            this.gid = gid;
+            this.permissions = permissions;
+            this.atime = atime;
+            this.mtime = mtime;
+            this.attributes = attributes;
+        }
+        
+        /**
+         * Determines if the file system object is a file on the remote file system.
+         * 
+         * @return true if and only if the object on the remote system can be considered to have "contents" that
+         * have the potential to be read and written as a byte stream.
+         */
+        public boolean isFile() {
+            if ((flags & ATTR_PERMISSIONS) == 0) return false;
+            return (permissions & S_IFMT) == S_IFREG;
+        }
+
+        /**
+         * Determines if the file system object is a directory on the remote file system.
+         * 
+         * @return true if and only if the object on the remote system is a directory.
+         * That is, it contains entries that can be interpreted as other files.
+         */
+        public boolean isDirectory() {
+            if ((flags & ATTR_PERMISSIONS) == 0) return false;
+            return (permissions & S_IFMT) == S_IFDIR;
+        }
+    }
+    
+    /**
+     * The following flags are defined for the 'permissions' field:
+     */
+    static final int
+        S_IFMT     = 0170000,   // bitmask for the file type bitfields
+        S_IFSOCK   = 0140000,   // socket
+        S_IFLNK    = 0120000,   // symbolic link
+        S_IFREG    = 0100000,   // regular file
+        S_IFBLK    = 0060000,   // block device
+        S_IFDIR    = 0040000,   // directory
+        S_IFCHR    = 0020000,   // character device
+        S_IFIFO    = 0010000,   // fifo
+        S_ISUID    = 0004000,   // set UID bit
+        S_ISGID    = 0002000,   // set GID bit (see below)
+        S_ISVTX    = 0001000,   // sticky bit (see below)
+        S_IRWXU    = 00700,     // mask for file owner permissions
+        S_IRUSR    = 00400,     // owner has read permission
+        S_IWUSR    = 00200,     // owner has write permission
+        S_IXUSR    = 00100,     // owner has execute permission
+        S_IRWXG    = 00070,     // mask for group permissions
+        S_IRGRP    = 00040,     // group has read permission
+        S_IWGRP    = 00020,     // group has write permission
+        S_IXGRP    = 00010,     // group has execute permission
+        S_IRWXO    = 00007,     // mask for permissions for others (not in group)
+        S_IROTH    = 00004,     // others have read permission
+        S_IWOTH    = 00002,     // others have write permisson
+        S_IXOTH    = 00001;     // others have execute permission
+    
+    final static class DirEntry {
+        /**
+         * `filename' is a file name being returned. It is a relative name within
+         * the directory, without any path components;
+         */
+        public final String filename;
+        
+        /**
+         * `longname' is an expanded format for the file name, similar to what
+         * is returned by "ls -l" on Unix systems.
+         * The format of the `longname' field is unspecified by this protocol.
+         * It MUST be suitable for use in the output of a directory listing
+         * command (in fact, the recommended operation for a directory listing
+         * command is to simply display this data).  However, clients SHOULD NOT
+         * attempt to parse the longname field for file attributes; they SHOULD
+         * use the attrs field instead.
+         */
+        public final String longname;
+        
+        /**
+         * `attrs' is the attributes of the file.
+         */
+        public final FileAttrs attrs;
+        
+        public DirEntry(String filename, String longname, FileAttrs attrs) {
+            this.filename = filename;
+            this.longname = longname;
+            this.attrs = attrs;
+        }
+    }
+    
+    /**
+     * Opaque representation of open file handle.
+     * Note: open file handle can be used only with service instance that 
+     * created the handle.
+     */
+    interface IFileHandle {
+        IFileSystem getService();
+    }
+    
+    /**
+     * Service specific error codes.
+     */
+    static final int
+    
+        /**
+         * Indicates end-of-file condition; for read() it means that no
+         * more data is available in the file, and for readdir() it
+         * indicates that no more files are contained in the directory.
+         */
+        STATUS_EOF = 0x10001,
+
+        /**
+         * This code is returned when a reference is made to a file which
+         * should exist but doesn't.
+         */
+        STATUS_NO_SUCH_FILE = 0x10002,
+
+        /**
+         * is returned when the authenticated user does not have sufficient
+         * permissions to perform the operation.
+         */
+        STATUS_PERMISSION_DENIED = 0x10003;
+    
+    /**
+     * The class to represent File System error reports. 
+     */
+    @SuppressWarnings("serial")
+    abstract static class FileSystemException extends IOException {
+        
+        protected FileSystemException(String message) {
+            super(message);
+        }
+        
+        protected FileSystemException(Exception x) {
+            super(x.getMessage());
+            initCause(x);
+        }
+        
+        /**
+         * Get error code. The code can be standard TCF error code or
+         * one of service specific codes, see STATUS_*. 
+         * @return error code.
+         */
+        public abstract int getStatus();
+    }
+
+    /**
+     * Open or create a file on a remote system.
+     * 
+     * @param file_name specifies the file name.  See 'File Names' for more information.
+     * @param flags is a bit mask of TCF_O_* flags.
+     * @param attrs specifies the initial attributes for the file.
+     *  Default values will be used for those attributes that are not specified.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken open(String file_name, int flags, FileAttrs attrs, DoneOpen done);
+    
+    interface DoneOpen {
+        void doneOpen(IToken token, FileSystemException error, IFileHandle handle);
+    }
+    
+    /**
+     * Close a file on a remote system.
+     * 
+     * @param handle is a handle previously returned in the response to
+     * open() or opendir().
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken close(IFileHandle handle, DoneClose done);
+    
+    interface DoneClose {
+        void doneClose(IToken token, FileSystemException error);
+    }
+    
+    /**
+     * Read bytes from an open file.
+     * In response to this request, the server will read as many bytes as it
+     * can from the file (up to `len'), and return them in a byte array.
+     * If an error occurs or EOF is encountered, the server may return
+     * fewer bytes then requested. Call back method doneRead() argument 'error'
+     * will be not null in case of error, and argument 'eof' will be
+     * true in case of EOF. For normal disk files, it is guaranteed
+     * that this will read the specified number of bytes, or up to end of file
+     * or error. For e.g. device files this may return fewer bytes than requested.
+     * 
+     * @param handle is an open file handle returned by open().
+     * @param offset is the offset (in bytes) relative
+     * to the beginning of the file from where to start reading.
+     * If offset < 0 then reading starts from current position in the file.
+     * @param len is the maximum number of bytes to read.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken read(IFileHandle handle, long offset, int len, DoneRead done);
+    
+    interface DoneRead {
+        void doneRead(IToken token, FileSystemException error, byte[] data, boolean eof);
+    }
+
+    /**
+     * Write bytes into an open file.
+     * The write will extend the file if writing beyond the end of the file.
+     * It is legal to write way beyond the end of the file; the semantics
+     * are to write zeroes from the end of the file to the specified offset
+     * and then the data.
+     * 
+     * @param handle is an open file handle returned by open().
+     * @param offset is the offset (in bytes) relative
+     * to the beginning of the file from where to start writing.
+     * If offset < 0 then writing starts from current position in the file.
+     * @param data is byte array that contains data for writing.
+     * @param data_pos if offset in 'data' of first byte to write.
+     * @param data_size is the number of bytes to write.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken write(IFileHandle handle, long offset,
+            byte[] data, int data_pos, int data_size, DoneWrite done);
+
+    interface DoneWrite {
+        void doneWrite(IToken token, FileSystemException error);
+    }
+    
+    /**
+     * Retrieve file attributes.
+     * 
+     * @param path - specifies the file system object for which
+     * status is to be returned.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken stat(String path, DoneStat done);
+
+    /**
+     * Retrieve file attributes.
+     * Unlike 'stat()', 'lstat()' does not follow symbolic links.
+     * 
+     * @param path - specifies the file system object for which
+     * status is to be returned.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken lstat(String path, DoneStat done);
+    
+    /**
+     * Retrieve file attributes for an open file (identified by the file handle).
+     * 
+     * @param handle is a file handle returned by 'open()'.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken fstat(IFileHandle handle, DoneStat done);
+    
+    interface DoneStat {
+        void doneStat(IToken token, FileSystemException error, FileAttrs attrs);
+    }
+    
+    /**
+     * Set file attributes.
+     * This request is used for operations such as changing the ownership,
+     * permissions or access times, as well as for truncating a file.
+     * An error will be returned if the specified file system object does
+     * not exist or the user does not have sufficient rights to modify the
+     * specified attributes.
+     * 
+     * @param path specifies the file system object (e.g. file or directory)
+     * whose attributes are to be modified.
+     * @param attrs specifies the modifications to be made to file attributes.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken setstat(String path, FileAttrs attrs, DoneSetStat done);
+    
+    /**
+     * Set file attributes for an open file (identified by the file handle).
+     * This request is used for operations such as changing the ownership,
+     * permissions or access times, as well as for truncating a file.
+     * 
+     * @param handle is a file handle returned by 'open()'.
+     * @param attrs specifies the modifications to be made to file attributes.
+     * @param done is call back object.
+     * @return pending command handle.
+     */
+    IToken fsetstat(IFileHandle handle, FileAttrs attrs, DoneSetStat done);
+    
+    interface DoneSetStat {
+        void doneSetStat(IToken token, FileSystemException error);
+    }
+    
+    /**
+     * The opendir() command opens a directory for reading.
+     * Once the directory has been successfully opened, files (and
+     * directories) contained in it can be listed using readdir() requests.
+     * When the client no longer wishes to read more names from the
+     * directory, it SHOULD call close() for the handle.  The handle
+     * should be closed regardless of whether an error has occurred or not.
+
+     * @param path - name of the directory to be listed (without any trailing slash).
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken opendir(String path, DoneOpen done);
+    
+    /**
+     * The files in a directory can be listed using the opendir() and
+     * readdir() requests.  Each readdir() request returns one
+     * or more file names with full file attributes for each file.  The
+     * client should call readdir() repeatedly until it has found the
+     * file it is looking for or until the server responds with a
+     * message indicating an error or end of file. The client should then
+     * close the handle using the close() request.
+     * Note: directory entries "." and ".." are NOT included into readdir()
+     * response.
+     * @param handle - file handle created by opendir()
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken readdir(IFileHandle handle, DoneReadDir done);
+    
+    interface DoneReadDir {
+        void doneReadDir(IToken token, FileSystemException error, DirEntry[] entries, boolean eof);
+    }
+    
+    /**
+     * Create a directory on the server.
+     * 
+     * @param path - specifies the directory to be created.
+     * @param attrs - new directory attributes.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken mkdir(String path, FileAttrs attrs, DoneMkDir done);
+    
+    interface DoneMkDir {
+        void doneMkDir(IToken token, FileSystemException error);
+    }
+
+    /**
+     * Remove a directory.
+     * An error will be returned if no directory
+     * with the specified path exists, or if the specified directory is not
+     * empty, or if the path specified a file system object other than a
+     * directory.
+     * 
+     * @param path - specifies the directory to be removed.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken rmdir(String path, DoneRemove done);
+    
+    interface DoneRemove {
+        void doneRemove(IToken token, FileSystemException error);
+    }
+
+    /**
+     * Retrieve file system roots - top level file system objects.
+     * UNIX file system can report just one root with path "/". Other types of systems
+     * can have more the one root. For example, Windows server can return multiple roots:
+     * one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
+     * the service must use forward slash as directory separator, and must start 
+     * absolute path with "/". Server should implement proper translation of
+     * protocol file names to OS native names and back. 
+     * 
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken roots(DoneRoots done);
+    
+    interface DoneRoots {
+        void doneRoots(IToken token, FileSystemException error, DirEntry[] entries);
+    }
+
+    /**
+     * Remove a file or symbolic link.
+     * This request cannot be used to remove directories.
+     * 
+     * @param file_name is the name of the file to be removed.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken remove(String file_name, DoneRemove done);
+    
+    /**
+     * Canonicalize any given path name to an absolute path.
+     * This is useful for converting path names containing ".." components or
+     * relative pathnames without a leading slash into absolute paths.
+     * 
+     * @param path specifies the path name to be canonicalized.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken realpath(String path, DoneRealPath done);
+    
+    interface DoneRealPath {
+        void doneRealPath(IToken token, FileSystemException error, String path);
+    }
+
+    /**
+     * Rename a file.
+     * It is an error if there already exists a file
+     * with the name specified by 'new_path'.  The server may also fail rename
+     * requests in other situations, for example if `old_path' and `new_path'
+     * point to different file systems on the server.
+     * 
+     * @param old_path is the name of an existing file or directory.
+     * @param new_path is the new name for the file or directory.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken rename(String old_path, String new_path, DoneRename done);
+    
+    interface DoneRename {
+        void doneRename(IToken token, FileSystemException error);
+    }
+
+    /**
+     * Read the target of a symbolic link.
+     * 
+     * @param path specifies the path name of the symbolic link to be read.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken readlink(String path, DoneReadLink done);
+    
+    interface DoneReadLink {
+        void doneReadLink(IToken token, FileSystemException error, String path);
+    }
+
+    /**
+     * Create a symbolic link on the server.
+     * 
+     * @param link_path specifies the path name of the symbolic link to be created.
+     * @param target_path specifies the target of the symbolic link.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken symlink(String link_path, String target_path, DoneSymLink done);
+    
+    interface DoneSymLink {
+        void doneSymLink(IToken token, FileSystemException error);
+    }
+
+    /**
+     * Copy a file on remote system.
+     * 
+     * @param src_path specifies the path name of the file to be copied.
+     * @param dst_path specifies destination file name.
+     * @param copy_permissions - if true then copy source file permissions.
+     * @param copy_ownership - if true then copy source file UID and GID.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken copy(String src_path, String dst_path,
+            boolean copy_permissions, boolean copy_ownership, DoneCopy done);
+    
+    interface DoneCopy {
+        void doneCopy(IToken token, FileSystemException error);
+    }
+    
+    /**
+     * Retrieve information about user account, which is used by server 
+     * to access file system on behalf of the client.
+     *   
+     * @param done - result call back object.
+     * @return pending command handle.
+     */
+    IToken user(DoneUser done);
+    
+    interface DoneUser {
+        void doneUser(IToken token, FileSystemException error,
+                int real_uid, int effective_uid, int real_gid, int effective_gid,
+                String home);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILineNumbers.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.math.BigInteger;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+/**
+ * Line numbers service associates locations in the source files with the corresponding
+ * machine instruction addresses in the executable object.
+ */
+public interface ILineNumbers extends IService {
+
+    static final String NAME = "LineNumbers";
+    
+    /**
+     * TextArea represent a continues area in source text mapped to
+     * continues range of code addresses.
+     * Line and columns are counted starting from 1.
+     * File name can be relative path, in such case client should 
+     * use TextArea directory name as origin for the path.
+     * File and directory names are valid on a host where code was compiled.
+     * It is client responsibility to map names to this host file system.    
+     */
+    final class CodeArea {
+        public final String directory;
+        public final String file;
+        public final int start_line;
+        public final int start_column;
+        public final int end_line;
+        public final int end_column;
+        public final Number start_address;
+        public final Number end_address;
+        public final int isa;
+        public final boolean is_statement;
+        public final boolean basic_block;
+        public final boolean prologue_end;
+        public final boolean epilogue_begin;
+        
+        public CodeArea(String directory, String file, int start_line, int start_column,
+                int end_line, int end_column, Number start_address, Number end_address, int isa,
+                boolean is_statement, boolean basic_block,
+                boolean prologue_end, boolean epilogue_begin) {
+            this.directory = directory;
+            this.file = file;
+            this.start_line = start_line;
+            this.start_column = start_column;
+            this.end_line = end_line;
+            this.end_column = end_column;
+            this.start_address = start_address;
+            this.end_address = end_address;
+            this.isa = isa;
+            this.is_statement = is_statement;
+            this.basic_block = basic_block;
+            this.prologue_end = prologue_end;
+            this.epilogue_begin = epilogue_begin;
+        }
+        
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof CodeArea)) return false;
+            CodeArea a = (CodeArea)o;
+            if (start_line != a.start_line) return false;
+            if (start_column != a.start_column) return false;
+            if (end_line != a.end_line) return false;
+            if (end_column != a.end_column) return false;
+            if (isa != a.isa) return false;
+            if (is_statement != a.is_statement) return false;
+            if (basic_block != a.basic_block) return false;
+            if (prologue_end != a.prologue_end) return false;
+            if (epilogue_begin != a.epilogue_begin) return false;
+            if (start_address != null && !start_address.equals(a.start_address)) return false;
+            if (start_address == null && a.start_address != null) return false;
+            if (end_address != null && !end_address.equals(a.end_address)) return false;
+            if (end_address == null && a.end_address != null) return false;
+            if (file != null && !file.equals(a.file)) return false;
+            if (file == null && a.file != null) return false;
+            if (directory != null && !directory.equals(a.directory)) return false;
+            if (directory == null && a.directory != null) return false;
+            return true;
+        }
+        
+        @Override
+        public int hashCode() {
+            int h = 0;
+            if (file != null) h += file.hashCode();
+            return h + start_line + start_column + end_line + end_column;
+        }
+        
+        @Override
+        public String toString() {
+            StringBuffer bf = new StringBuffer();
+            bf.append('[');
+            if (directory != null) {
+                bf.append(directory);
+                bf.append(':');
+            }
+            if (file != null) {
+                bf.append(file);
+                bf.append(':');
+            }
+            bf.append(start_line);
+            if (start_column != 0) {
+                bf.append('.');
+                bf.append(start_column);
+            }
+            bf.append("..");
+            bf.append(end_line);
+            if (end_column != 0) {
+                bf.append('.');
+                bf.append(end_column);
+            }
+            bf.append(" -> ");
+            if (start_address != null) {
+                bf.append("0x");
+                bf.append(new BigInteger(start_address.toString()).toString(16));
+            }
+            else {
+                bf.append('0');
+            }
+            bf.append("..");
+            if (end_address != null) {
+                bf.append("0x");
+                bf.append(new BigInteger(end_address.toString()).toString(16));
+            }
+            else {
+                bf.append('0');
+            }
+            if (isa != 0) {
+                bf.append(",isa ");
+                bf.append(isa);
+            }
+            if (is_statement) {
+                bf.append(",statement");
+            }
+            if (basic_block) {
+                bf.append(",basic block");
+            }
+            if (prologue_end) {
+                bf.append(",prologue end");
+            }
+            if (epilogue_begin) {
+                bf.append(",epilogue begin");
+            }
+            bf.append(']');
+            return bf.toString();
+        }
+    }
+    
+    IToken mapToSource(String context_id, Number start_address, Number end_address, DoneMapToSource done);
+    
+    interface DoneMapToSource {
+        void doneMapToSource(IToken token, Exception error, CodeArea[] areas);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * ILocator service uses transport layer to search for peers and to collect data about
+ * peer’s attributes and capabilities (services). Discovery mechanism depends on transport protocol
+ * and is part of that protocol handler. Targets, known to other hosts, can be found through
+ * remote instances of ILocator service. Automatically discovered targets require no further
+ * configuration. Additional targets can be configured manually.
+ * 
+ * Clients should use Protocol.getLocator() to obtain local instance of ILocator,
+ * then ILocator.getPeers() can be used to get list of available peers (hosts and targets).
+ */
+
+public interface ILocator extends IService {
+
+    static final String NAME = "Locator";
+
+    /**
+     * Peer data retention period in milliseconds.
+     */
+    static final long DATA_RETENTION_PERIOD = 60 * 1000;
+    
+    /**
+     * Auto-configuration protocol version.
+     */
+    static char CONF_VERSION = '2';
+
+    /**
+     * Auto-configuration command and response codes.
+     */
+    static final int
+        CONF_REQ_INFO = 1,
+        CONF_PEER_INFO = 2,
+        CONF_REQ_SLAVES = 3,
+        CONF_SLAVES_INFO = 4;
+
+    /**
+     * @return Locator service name: "Locator"
+     */
+    String getName();
+
+    /** 
+     * Get map (ID -> IPeer) of available peers (hosts and targets).
+     * The method return cached (currently known to the framework) list of peers.
+     * The list is updated according to event received from transport layer
+     */
+    Map<String,IPeer> getPeers();
+    
+    /**
+     * Redirect this service channel to given peer using this service as a proxy.
+     * @param peer_id - Peer ID.
+     */
+    IToken redirect(String peer_id, DoneRedirect done);
+    
+    interface DoneRedirect {
+        void doneRedirect(IToken token, Exception error);
+    }
+    
+    /**
+     * Call back after TCF messages sent to this target up to this moment are delivered.
+     * This method is intended for synchronization of messages
+     * across multiple channels.
+     * 
+     * Note: Cross channel synchronization can reduce performance and throughput.
+     * Most clients don't need channel synchronization and should not call this method. 
+     *  
+     * @param done will be executed by dispatch thread after communication 
+     * messages are delivered to corresponding targets.
+     * 
+     * This is internal API, TCF clients should use {@code org.eclipse.tm.tcf.protocol.Protocol}.
+     */
+    IToken sync(DoneSync done);
+    
+    interface DoneSync {
+        void doneSync(IToken token);
+    }
+
+    /**
+     * Add a listener for ILocator service events.
+     */
+    void addListener(LocatorListener listener);
+
+    /**
+     * Remove a listener for ILocator service events.
+     */
+    void removeListener(LocatorListener listener);
+
+    interface LocatorListener {
+        /**
+         * A new peer is added into locator peer table.
+         * @param peer
+         */
+        void peerAdded(IPeer peer);
+
+        /**
+         * Peer attributes have changed.
+         * @param peer
+         */
+        void peerChanged(IPeer peer);
+
+        /**
+         * A peer is removed from locator peer table.
+         * @param id - peer ID
+         */
+        void peerRemoved(String id);
+        
+        /**
+         * Peer heart beat detected.
+         * @param id - peer ID
+         */
+        void peerHeartBeat(String id);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * IMemory service provides basic operations to read/write memory on a target.
+ */
+public interface IMemory extends IService {
+
+    static final String NAME = "Memory";
+
+    /**
+     * Context property names.
+     */
+    static final String
+        PROP_ID = "ID",                         /** String, ID of the context, same as getContext command argument */
+        PROP_PARENT_ID = "ParentID",            /** String, ID of a parent context */
+        PROP_PROCESS_ID = "ProcessID",          /** String, process ID, see Processes service */
+        PROP_BIG_ENDIAN = "BigEndian",          /** Boolean, true if memory is big-endian */
+        PROP_ADDRESS_SIZE = "AddressSize",      /** Number, size of memory address in bytes */
+        PROP_NAME = "Name",                     /** String, name of the context, can be used for UI purposes */
+        PROP_START_BOUND = "StartBound",        /** Number, lowest address (inclusive) which is valid for the context */
+        PROP_END_BOUND = "EndBound",            /** Number, highest address (inclusive) which is valid for the context */
+        PROP_ACCESS_TYPES = "AccessTypes";      /** Array of String, the access types allowed for this context */
+    
+    /**
+     * Values of "AccessTypes".
+     * Target system can support multiple different memory access types, like instruction and data access.
+     * Different access types can use different logic for address translation and memory mapping, so they can
+     * end up accessing different data bits, even if address is the same.
+     * Each distinct access type should be represented by separate memory context.
+     * A memory context can represent multiple access types if they are equivalent - all access same memory bits.
+     * Same data bits can be exposed through multiple memory contexts.
+     */
+    static final String
+        ACCESS_INSTRUCTION = "instruction",     /** Context represent instructions fetch access */
+        ACCESS_DATA = "data",                   /** Context represents data access */
+        ACCESS_IO = "io",                       /** Context represents IO peripherals */
+        ACCESS_USER = "user",                   /** Context represents a user (e.g. application running in Linux) view to memory */
+        ACCESS_SUPERVISOR = "supervisor",       /** Context represents a supervisor (e.g. Linux kernel) view to memory */
+        ACCESS_HYPERVISOR = "hypervisor",       /** Context represents a hypervisor view to memory */
+        ACCESS_VIRTUAL = "virtual",             /** Context uses virtual addresses */
+        ACCESS_PHYSICAL = "physical",           /** Context uses physical addresses */
+        ACCESS_CACHE = "cache",                 /** Context is a cache */
+        ACCESS_TLB = "tlb";                     /** Context is a TLB memory */
+    
+    /**
+     * Retrieve context info for given context ID.
+     *   
+     * @param id – context ID. 
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context data.
+         */
+        void doneGetContext(IToken token, Exception error, MemoryContext context);
+    }
+
+    /**
+     * Retrieve contexts available for memory commands.
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service.
+     *  
+     * @param parent_context_id – parent context ID. Can be null –
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getChildren commands.
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+
+    /**
+     * Memory access mode:
+     * Carry on when some of the memory cannot be accessed and
+     * return MemoryError at the end if any of the bytes
+     * were not processed correctly.
+     */
+    final static int MODE_CONTINUEONERROR = 0x1;
+
+    /**
+     * Memory access mode:
+     * Verify result of memory operations (by reading and comparing).
+     */
+    final static int MODE_VERIFY = 0x2;
+
+    interface MemoryContext {
+
+        /** 
+         * Get context ID.
+         * @return context ID.
+         */
+        String getID();
+
+        /** 
+         * Get parent context ID.
+         * @return parent ID.
+         */
+        String getParentID();
+        
+        /**
+         * Get process ID, if applicable.
+         * @return process ID.
+         */
+        String getProcessID();
+        
+        /**
+         * Get memory endianess.
+         * @return true if memory id big-endian.
+         */
+        boolean isBigEndian();
+        
+        /**
+         * Get memory address size.
+         * @return number of bytes used to store memory address value.
+         */
+        int getAddressSize();
+        
+        /**
+         * Get memory context name.
+         * The name can be used for UI purposes.
+         * @return context name.
+         */
+        String getName();
+        
+        /**
+         * Get lowest address (inclusive) which is valid for the context.
+         * @return lowest address.
+         */
+        Number getStartBound();
+        
+        /**
+         * Get highest address (inclusive) which is valid for the context.
+         * @return highest address.
+         */
+        Number getEndBound();
+        
+        /**
+         * Get the access types allowed for this context.
+         * @return collection of access type names.
+         */
+        Collection<String> getAccessTypes();
+
+        /** 
+         * Get context properties.
+         * @return all available context properties.
+         */
+        Map<String,Object> getProperties();
+
+        /**
+         * Set target memory.
+         * If 'word_size' is 0 it means client does not care about word size.
+         */
+        IToken set(Number addr, int word_size, byte[] buf,
+                int offs, int size, int mode, DoneMemory done);
+
+        /**
+         * Read target memory.
+         */
+        IToken get(Number addr, int word_size, byte[] buf,
+                int offs, int size, int mode, DoneMemory done);
+
+        /**
+         * Fill target memory with given pattern.
+         * 'size' is number of bytes to fill.
+         */
+        IToken fill(Number addr, int word_size, byte[] value,
+                int size, int mode, DoneMemory done);
+    }
+
+    /**
+     * Client call back interface for set(), get() and fill() commands.
+     */
+    interface DoneMemory {
+        public void doneMemory(IToken token, MemoryError error);
+    }
+
+    class MemoryError extends Exception {
+
+        private static final long serialVersionUID = 1L;
+        
+        public MemoryError(String msg) {
+            super(msg);
+        }
+    }
+
+    /**
+     * ErrorOffset interface can be implemented by MemoryError object,
+     * which is returned by get, set and fill commands.
+     *
+     * get/set/fill () returns this exception when reading failed
+     * for some but not all bytes, and MODE_CONTINUEONERROR
+     * has been set in mode. (For example, when only part of the request
+     * translates to valid memory addresses.)
+     * Exception.getMessage can be used for generalized message of the
+     * possible reasons of partial memory operation.
+     */
+    interface ErrorOffset {
+
+        // Error may have per byte information
+        final static int 
+            BYTE_VALID        = 0x00,
+            BYTE_UNKNOWN      = 0x01, // e.g. out of range
+            BYTE_INVALID      = 0x02,
+            BYTE_CANNOT_READ  = 0x04,
+            BYTE_CANNOT_WRITE = 0x08;
+
+        int getStatus(int offset);
+
+        /**
+         * Returns the detail message string about the
+         * byte associated with specified location.
+         * @return  the detail error message string.
+         */
+        String getMessage(int offset);
+
+    }
+
+    /**
+     * Add memory service event listener.
+     * @param listener - event listener implementation.
+     */
+    void addListener(MemoryListener listener);
+
+    /**
+     * Remove memory service event listener.
+     * @param listener - event listener implementation.
+     */
+    void removeListener(MemoryListener listener);
+
+    /**
+     * Memory event listener is notified when memory context hierarchy
+     * changes, and when memory is modified by memory service commands. 
+     */
+    interface MemoryListener {
+
+        /**
+         * Called when a new memory access context(s) is created.
+         */
+        void contextAdded(MemoryContext[] contexts);
+
+        /**
+         * Called when a memory access context(s) properties changed.
+         */
+        void contextChanged(MemoryContext[] contexts);
+
+        /**
+         * Called when memory access context(s) is removed.
+         */
+        void contextRemoved(String[] context_ids);
+
+        /**
+         * Called when target memory content was changed and clients 
+         * need to update themselves. Clients, at least, should invalidate
+         * corresponding cached memory data.
+         * Not every change is notified - it is not possible,
+         * only those, which are not caused by normal execution of the debuggee.
+         * ‘addr’ and ‘size’ can be null if unknown.
+         */
+        void memoryChanged(String context_id, Number[] addr, long[] size);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IProcesses.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * IProcesses service provides access to the target OS's process 
+ * information, allows to start and terminate a process, and allows
+ * to attach and detach a process for debugging. Debug services,
+ * like IMemory and IRunControl, require a process to be attached
+ * before they can access it.
+ * 
+ * If a process is started by this service, its standard input/output streams are 
+ * available for client to read/write using Streams service. Stream type of such
+ * streams is set to "Processes".
+ */
+public interface IProcesses extends IService {
+
+    static final String NAME = "Processes";
+    
+    /**
+     * Retrieve context info for given context ID.
+     * A context corresponds to an execution thread, process, address space, etc.
+     * Context IDs are valid across TCF services, so it is allowed to issue
+     * 'IProcesses.getContext' command with a context that was obtained,
+     * for example, from Memory service.
+     * However, 'Processes.getContext' is supposed to return only process specific data,
+     * If the ID is not a process ID, 'IProcesses.getContext' may not return any
+     * useful information
+     *    
+     * @param id – context ID. 
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context data.
+         */
+        void doneGetContext(IToken token, Exception error, ProcessContext context);
+    }
+
+    /**
+     * Retrieve children of given context.
+     *   
+     * @param parent_context_id – parent context ID. Can be null –
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * @param attached_only - if true return only attached process IDs.
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getChildren(String parent_context_id, boolean attached_only, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * Context property names.
+     */
+    static final String
+        /** The TCF context ID */
+        PROP_ID = "ID",
+        
+        /** The TCF parent context ID */
+        PROP_PARENTID = "ParentID",
+        
+        /** Is the context attached */
+        PROP_ATTACHED = "Attached",
+        
+        /** Can terminate the context */
+        PROP_CAN_TERMINATE = "CanTerminate",
+        
+        /** Process name. Client UI can show this name to a user */
+        PROP_NAME = "Name",
+        
+        /** Process standard input stream ID */
+        PROP_STDIN_ID = "StdInID",
+        
+        /** Process standard output stream ID */
+        PROP_STDOUT_ID = "StdOutID",
+        
+        /** Process standard error stream ID */
+        PROP_STDERR_ID = "StdErrID";
+    
+    interface ProcessContext {
+        
+        /** 
+         * Get context ID.
+         * Same as getProperties().get(“ID”)
+         */
+        String getID();
+
+        /**
+         * Get parent context ID.
+         * Same as getProperties().get(“ParentID”)
+         */
+        String getParentID();
+
+        /**
+         * Get process name.
+         * Client UI can show this name to a user.
+         * Same as getProperties().get(“Name”)
+         */
+        String getName();
+
+        /**
+         * Utility method to read context property PROP_ATTACHED.
+         * Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+         * @return value of PROP_ATTACHED.
+         */
+        boolean isAttached();
+
+        /**
+         * Utility method to read context property PROP_CAN_TERMINATE.
+         * @return value of PROP_CAN_TERMINATE.
+         */
+        boolean canTerminate();
+
+        /**
+         * Get all available context properties.
+         * @return Map 'property name' -> 'property value'
+         */
+        Map<String, Object> getProperties();
+        
+        /**
+         * Attach debugger to a process.
+         * Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+         * @param done - call back interface called when operation is completed.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken attach(DoneCommand done);
+
+        /**
+         * Detach debugger from a process.
+         * Process execution will continue without debugger supervision.
+         * @param done - call back interface called when operation is completed.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken detach(DoneCommand done);
+        
+        /**
+         * Terminate a process. 
+         * @param done - call back interface called when operation is completed.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken terminate(DoneCommand done);
+    }
+    
+    /**
+     * Call-back interface to be called when command is complete.
+     */
+    interface DoneCommand {
+        void doneCommand(IToken token, Exception error);
+    }
+    
+    /**
+     * Signal property names used by "getSignalList" command.
+     */
+    static final String
+        /** Number, bit position in the signal mask */
+        SIG_INDEX = "Index",
+        
+        /** String, signal name, for example "SIGHUP" */
+        SIG_NAME = "Name",
+        
+        /** Number, signal code, as defined by OS */
+        SIG_CODE = "Code",
+        
+        /** String, human readable description of the signal */
+        SIG_DESCRIPTION = "Description";
+    
+    /**
+     * Get list of signals that can be send to the process.
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken getSignalList(String context_id, DoneGetSignalList done);
+
+    /**
+     * Call-back interface to be called when "getSignalList" command is complete.
+     */
+    interface DoneGetSignalList {
+        void doneGetSignalList(IToken token, Exception error, Collection<Map<String,Object>> list);
+    }
+    
+    /**
+     * Get process or thread signal mask.
+     * Bits in the mask control how signals should be handled by debug agent.
+     * When new context is created it inherits the mask from its parent.
+     * If context is not attached the command will return an error. 
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken getSignalMask(String context_id, DoneGetSignalMask done);
+    
+    /**
+     * Call-back interface to be called when "getSignalMask" command is complete.
+     */
+    interface DoneGetSignalMask {
+        /**
+         * @param token - command handle.
+         * @param dont_stop - bit-set of signals that should suspend execution of the context.
+         * @param dont_pass - bit-set of signals that should not be delivered to the context.
+         * @param pending - bit-set of signals that are generated but not delivered yet.
+         * Note: "pending" is meaningful only if the context is suspended.
+         */
+        void doneGetSignalMask(IToken token, Exception error, int dont_stop, int dont_pass, int pending);
+    }
+    
+    /**
+     * Set process or thread signal mask. 
+     * Bits in the mask control how signals should be handled by debug agent.
+     * If context is not attached the command will return an error. 
+     * @param dont_stop - bit-set of signals that should not suspend execution of the context.
+     * By default, debugger suspends a context before it receives a signal.  
+     * @param dont_pass - bit-set of signals that should not be delivered to the context.
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken setSignalMask(String context_id, int dont_stop, int dont_pass, DoneCommand done);
+
+    /**
+     * Send a signal to a process or thread.
+     * @param context_id - context ID.
+     * @param signal - signal code.
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken signal(String context_id, long signal, DoneCommand done);
+
+    /**
+     * Get default set of environment variables used to start a new process.
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken getEnvironment(DoneGetEnvironment done);
+    
+    /**
+     * Call-back interface to be called when "getEnvironment" command is complete.
+     */
+    interface DoneGetEnvironment {
+        void doneGetEnvironment(IToken token, Exception error, Map<String,String> environment);
+    }
+
+    /**
+     * Start a new process on remote machine.
+     * @param directory - initial value of working directory for the process.
+     * @param file - process image file.
+     * @param command_line - command line arguments for the process.
+     * @param environment - map of environment variables for the process,
+     * if null then default set of environment variables will be used. 
+     * @param attach - if true debugger should be attached to the process.
+     * @param done - call back interface called when operation is completed.
+     * @return pending command handle, can be used to cancel the command.
+     */
+    IToken start(String directory, String file,
+            String[] command_line, Map<String,String> environment,
+            boolean attach, DoneStart done);
+    
+    /**
+     * Call-back interface to be called when "start" command is complete.
+     */
+    interface DoneStart {
+        void doneStart(IToken token, Exception error, ProcessContext process);
+    }
+    
+    /**
+     * Add processes service event listener.
+     * @param listener - event listener implementation.
+     */
+    void addListener(ProcessesListener listener);
+
+    /**
+     * Remove processes service event listener.
+     * @param listener - event listener implementation.
+     */
+    void removeListener(ProcessesListener listener);
+
+    /**
+     * Process event listener is notified when a process exits.
+     * Event are reported only for processes that were started by 'start' command. 
+     */
+    interface ProcessesListener {
+        
+        /**
+         * Called when a process exits.
+         * @param process_id - process context ID
+         * @param exit_code - process exit code
+         */
+        void exited(String process_id, int exit_code);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRegisters.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * IRegisters service provides access to target CPU register values and properties.
+ */
+public interface IRegisters extends IService {
+
+    static final String NAME = "Registers";
+
+    /**
+     * Context property names.
+     */
+    static final String
+        PROP_ID = "ID",                         /** String, ID of the context */
+        PROP_PARENT_ID = "ParentID",            /** String, ID of a parent context */
+        PROP_PROCESS_ID = "ProcessID",          /** String, process ID */
+        PROP_NAME = "Name",                     /** String, context name */
+        PROP_DESCRIPTION = "Description",       /** String, context description */
+        PROP_SIZE = "Size",                     /** Number, context size in bytes. Byte arrays in get/set commands should be same size */
+        PROP_READBLE = "Readable",              /** Boolean, true if context value can be read */
+        PROP_READ_ONCE = "ReadOnce",            /** Boolean, true if reading the context (register) destroys its current value */
+        PROP_WRITEABLE = "Writeable",           /** Boolean, true if context value can be written */
+        PROP_WRITE_ONCE = "WriteOnce",          /** Boolean, true if register value can not be overwritten - every write counts */
+        PROP_SIDE_EFFECTS = "SideEffects",      /** Boolean, true if writing the context can change values of other registers */
+        PROP_VOLATILE = "Volatile",             /** Boolean, true if the register value can change even when target is stopped */
+        PROP_FLOAT = "Float",                   /** Boolean, true if the register value is a floating-point value */
+        PROP_BIG_ENDIAN = "BigEndian",          /** Boolean, true if big endian */
+        PROP_LEFT_TO_RIGHT = "LeftToRight",     /** Boolean, true if the lowest numbered bit should be shown to user as the left-most bit */
+        PROP_FIST_BIT = "FirstBit",             /** Number, bit numbering base (0 or 1) to use when showing bits to user */ 
+        PROP_BITS = "Bits",                     /** Number, if context is a bit field, contains the field bit numbers in the parent context */
+        PROP_VALUES = "Values",                 /** Array of Map, predefined names (mnemonics) for some of context values */
+        PROP_MEMORY_ADDRESS = "MemoryAddress",  /** Number, the address of a memory mapped register */
+        PROP_MEMORY_CONTEXT = "MemoryContext",  /** String, the context ID of a memory context in which a memory mapped register is located */
+        PROP_CAN_SEARCH = "CanSearch",          /** Array of String, a list of attribute names which can be searched for starting on this context */
+        PROP_ROLE = "Role";                     /** String, the role the register plays in a program execution */
+    
+    /**
+     * Values of context property "Role".
+     */
+    static final String
+        ROLE_PC = "PC",                         /** Program counter. Defines instruction to execute next */
+        ROLE_SP = "SP",                         /** Register defining the current stack pointer location */
+        ROLE_FP = "FP",                         /** Register defining the current frame pointer location */
+        ROLE_RET = "RET",                       /** Register used to store the return address for calls */
+        ROLE_CORE = "CORE";                     /** Indicates register or register groups which belong to the core state */
+    
+    /**
+     * Search filter properties.
+     */
+    static final String
+        SEARCH_NAME = "Name",                   /** The name of the property this filter applies too */
+        SEARCH_EQUAL_VALUE = "EqualValue";      /** The value which is searched for */
+        
+    /**
+     * Retrieve context info for given context ID.
+     *   
+     * @param id – context ID. 
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context data.
+         */
+        void doneGetContext(IToken token, Exception error, RegistersContext context);
+    }
+
+    /**
+     * Retrieve contexts available for registers commands.
+     * A context corresponds to an execution thread, stack frame, registers group, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service.
+     *  
+     * @param parent_context_id – parent context ID. Can be null –
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getChildren commands.
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * RegistersContext objects represent register groups, registers and bit fields. 
+     */
+    interface RegistersContext {
+        /**
+         * Get Context ID.
+         * @return context ID.
+         */
+        String getID();
+        
+        /**
+         * Get parent context ID.
+         * @return parent context ID.
+         */
+        String getParentID();
+        
+        /**
+         * Get process ID, if applicable.
+         * @return process ID.
+         */
+        String getProcessID();
+        
+        /**
+         * Get context (register, register group, bit field) name.
+         * @return context name.
+         */
+        String getName();
+        
+        /**
+         * Get context description.
+         * @return context description.
+         */
+        String getDescription();
+        
+        /**
+         * Get context size in bytes.
+         * Byte arrays in get()/set() methods should be same size.
+         * Hardware register can be smaller then this size, for example in case
+         * when register size is not an even number of bytes. In such case implementation
+         * should add/remove padding that consist of necessary number of zero bits.
+         * @return context size in bytes.
+         */
+        int getSize();
+        
+        /**
+         * Check if context value can be read.
+         * @return true if can read value of the context.
+         */
+        boolean isReadable();
+        
+        /**
+         * Check if reading the context (register) destroys its current value -
+         * it can be read only once.
+         * @return true if read-once register.
+         */
+        boolean isReadOnce();
+        
+        /**
+         * Check if context value can be written.
+         * @return true if can write value of the context.
+         */
+        boolean isWriteable();
+        
+        /**
+         * Check if register value can not be overwritten - every write counts.
+         * @return true if write-once register.
+         */
+        boolean isWriteOnce();
+        
+        /**
+         * Check if writing the context can change values of other registers. 
+         * @return true if has side effects.
+         */
+        boolean hasSideEffects();
+        
+        /**
+         * Check if the register value can change even when target is stopped.
+         * @return true if the register value can change at any time.
+         */
+        boolean isVolatile();
+        
+        /**
+         * Check if the register value is a floating-point value.
+         * @return true if a floating-point register.
+         */
+        boolean isFloat();
+        
+        /**
+         * Check endianess of the context.
+         * Big endian means decreasing numeric significance with increasing bit number. 
+         * The endianess is used to encode and decode values of get, getm, set and setm commands.
+         * @return true if big endian.
+         */
+        boolean isBigEndian();
+        
+        /**
+         * Check if the lowest numbered bit (i.e. bit #0 or bit #1 depending on
+         * getFirstBitNumber() value) should be shown to user as the left-most bit or
+         * the right-most bit.
+         * @return true if the first bit is left-most bit.
+         */
+        boolean isLeftToRight();
+        
+        /**
+         * If the context has bit field children, bit positions of the fields
+         * can be zero-based or 1-based.
+         * @return first bit position - 0 or 1.
+         */
+        int getFirstBitNumber();
+        
+        /**
+         * If context is a bit field, get the field bit numbers in parent context. 
+         * @return array of bit numbers.
+         */
+        int[] getBitNumbers();
+        
+        /**
+         * A context can have predefined names (mnemonics) for some its values.
+         * This method returns a list of such named values.
+         * @return array of named values or null.
+         */
+        NamedValue[] getNamedValues();
+        
+        /**
+         * Get the address of a memory mapped register.
+         * @return address.
+         */
+        Number getMemoryAddress();
+        
+        /**
+         * Get the context ID of a memory context in which a memory mapped register is located. 
+         * @return memory context ID.
+         */
+        String getMemoryContext();
+        
+        /**
+         * Get a list of property names which can be searched for starting on this context
+         * @return collection of property names.
+         */
+        Collection<String> canSearch();
+        
+        /**
+         * Get the role the register plays in a program execution.
+         * @return role name.
+         */
+        String getRole();
+
+        /**
+         * Get complete map of context properties.
+         * @return map of all available context properties.
+         */
+        Map<String,Object> getProperties();
+        
+        /**
+         * Read value of the context.
+         * @param done - call back object.
+         * @return - pending command handle.
+         */
+        IToken get(DoneGet done);
+        
+        /**
+         * Set value of the context.
+         * @param value - value to write into the context.
+         * @param done - call back object.
+         * @return - pending command handle.
+         */
+        IToken set(byte[] value, DoneSet done);
+        
+        /**
+         * Search register contexts that passes given search filter.
+         * Search is only supported for properties listed in the "CanSearch" property.
+         * @param filter - properties bag that defines search filter.
+         * @param done - call back object.
+         * @return - pending command handle.
+         */
+        IToken search(Map<String,Object> filter, DoneSearch done);
+    }
+    
+    /**
+     * A register context can have predefined names (mnemonics) for some its values.
+     * NamedValue objects represent such values. 
+     */
+    interface NamedValue {
+        /**
+         * Get value associated with the name.
+         * @return the value as an array of bytes.
+         */
+        byte[] getValue();
+        
+        /**
+         * Get name (mnemonic) of the value.
+         * @return value name.
+         */
+        String getName();
+        
+        /**
+         * Get human readable description of the value.
+         * @return value description.
+         */
+        String getDescription();
+    }
+    
+    /**
+     * Read values of multiple locations in registers.
+     * @param locs - array of data locations.
+     * @param done - call back object.
+     * @return - pending command handle.
+     */
+    IToken getm(Location[] locs, DoneGet done);
+    
+    /**
+     * Set values of multiple locations in registers.
+     * @param locs - array of data locations.
+     * @param value - value to write into the context.
+     * @param done - call back object.
+     * @return - pending command handle.
+     */
+    IToken setm(Location[] locs, byte[] value, DoneSet done);
+
+    /**
+     * Class Location represents value location in register context
+     */
+    final class Location {
+        /** Register context ID */
+        public final String id; 
+
+        /** offset in the context, in bytes */
+        public final int offs;
+
+        /** value size in byte */
+        public final int size;
+
+        public Location(String id, int offs, int size) {
+            this.id = id;
+            this.offs = offs;
+            this.size = size;
+        }
+    }
+
+    /**
+     * 'get' command call back interface.
+     */
+    interface DoneGet {
+        /**
+         * Called when value retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param value – context value as array of bytes.
+         */
+        void doneGet(IToken token, Exception error, byte[] value);
+    }
+    
+    /**
+     * 'set' command call back interface.
+     */
+    interface DoneSet {
+        /**
+         * Called when value setting is done.
+         * @param token - command handle.
+         * @param error – error description if operation failed, null if succeeded.
+         */
+        void doneSet(IToken token, Exception error);
+    }
+    
+    /**
+     * 'search' command call back interface.
+     */
+    interface DoneSearch {
+        /**
+         * Called when context search is done.
+         * @param token - command handle.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param paths - array of paths to each context with properties matching the filter
+         */
+        void doneSearch(IToken token, Exception error, String[][] paths);
+    }
+
+    /**
+     * Add registers service event listener.
+     * @param listener - event listener implementation.
+     */
+    void addListener(RegistersListener listener);
+
+    /**
+     * Remove registers service event listener.
+     * @param listener - event listener implementation.
+     */
+    void removeListener(RegistersListener listener);
+
+    /**
+     * Registers event listener is notified when registers context hierarchy
+     * changes, and when a register is modified by the service commands. 
+     */
+    interface RegistersListener {
+
+        /**
+         * Called when register context properties changed.
+         * Most targets have static set of registers and register properties.
+         * Such targets never generate this event. However, some targets,
+         * for example, JTAG probes, allow user to modify register definitions.
+         * Clients should flush all cached register context data. 
+         */
+        void contextChanged();
+
+        /**
+         * Called when register content was changed and clients 
+         * need to update themselves. Clients, at least, should invalidate
+         * corresponding cached registers data.
+         * Not every change is notified - it is not possible,
+         * only those, which are not caused by normal execution of the debuggee.
+         * At least, changes caused by "set" command should be notified.
+         * @param id - register context ID.
+         */
+        void registerChanged(String id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+public interface IRunControl extends IService {
+
+    static final String NAME = "RunControl";
+    
+    /**
+     * Context property names.
+     */
+    static final String
+        PROP_ID = "ID",
+        PROP_PARENT_ID = "ParentID",
+        PROP_PROCESS_ID = "ProcessID",
+        PROP_IS_CONTAINER = "IsContainer",
+        PROP_HAS_STATE = "HasState",
+        PROP_CAN_RESUME = "CanResume",
+        PROP_CAN_COUNT = "CanCount",
+        PROP_CAN_SUSPEND = "CanSuspend",
+        PROP_CAN_TERMINATE = "CanTerminate";
+    
+    /**
+     * Context resume modes.  
+     */
+    static final int
+        
+        RM_RESUME = 0,
+        
+        /**
+         * Step over a single instruction.
+         * If the instruction is a function call then don't stop until the function returns.
+         */
+        RM_STEP_OVER = 1,
+        
+        /**
+         * Step a single instruction.
+         * If the instruction is a function call then stop at first instruction of the function.
+         */
+        RM_STEP_INTO = 2,
+        
+        /**
+         * Step over a single source code line.
+         * If the line contains a function call then don't stop until the function returns.
+         */
+        RM_STEP_OVER_LINE = 3,
+        
+        /**
+         * Step a single source code line.
+         * If the line contains a function call then stop at first line of the function.
+         */
+        RM_STEP_INTO_LINE = 4,
+        
+        /**
+         * Run until control returns from current function.
+         */
+        RM_STEP_OUT = 5,
+        
+        /**
+         * Start running backwards.
+         * Execution will continue until suspended by command or breakpoint.
+         */
+        RM_REVERSE_RESUME = 6,
+        
+        /**
+         * Reverse of RM_STEP_OVER - run backwards over a single instruction.
+         * If the instruction is a function call then don't stop until get out of the function.
+         */
+        RM_REVERSE_STEP_OVER = 7,
+        
+        /**
+         * Reverse of RM_STEP_INTO.
+         * This effectively "un-executes" the previous instruction
+         */
+        RM_REVERSE_STEP_INTO = 8,
+        
+        /**
+         * Reverse of RM_STEP_OVER_LINE.
+         * Resume backward execution of given context until control reaches an instruction that belongs
+         * to a different source line. 
+         * If the line contains a function call then don't stop until get out of the function.
+         * Error is returned if line number information not available.
+         */
+        RM_REVERSE_STEP_OVER_LINE = 9,
+        
+        /**
+         * Reverse of RM_STEP_INTO_LINE,
+         * Resume backward execution of given context until control reaches an instruction that belongs
+         * to a different line of source code.
+         * If a function is called, stop at the beginning of the last line of the function code.
+         * Error is returned if line number information not available.
+         */
+        RM_REVERSE_STEP_INTO_LINE = 10,
+        
+        /**
+         * Reverse of RM_STEP_OUT.
+         * Resume backward execution of the given context until control reaches the point where the current function was called.
+         */
+        RM_REVERSE_STEP_OUT = 11,
+        
+        /**
+         * Step over instructions until PC is outside the specified range.
+         * If any function call within the range is considered to be in range.
+         */
+        RM_STEP_OVER_RANGE = 12,
+        
+        /**
+         * Step instruction until PC is outside the specified range for any reason.
+         */
+        RM_STEP_INTO_RANGE = 13,
+        
+        /**
+         * Reverse of RM_STEP_OVER_RANGE
+         */
+        RM_REVERSE_STEP_OVER_RANGE = 14,
+        
+        /**
+         * Reverse of RM_STEP_INTO_RANGE
+         */
+        RM_REVERSE_STEP_INTO_RANGE = 15;
+    
+    /**
+     * State change reason of a context.
+     * Reason can be any text, but if it is one of predefined strings,
+     * a generic client might be able to handle it better. 
+     */
+    static final String
+        REASON_USER_REQUEST = "Suspended",
+        REASON_STEP = "Step",
+        REASON_BREAKPOINT = "Breakpoint",
+        REASON_EXCEPTION = "Exception",
+        REASON_CONTAINER = "Container",
+        REASON_WATCHPOINT = "Watchpoint",
+        REASON_SIGNAL = "Signal",
+        REASON_SHAREDLIB = "Shared Library",
+        REASON_ERROR = "Error";
+    
+    /**
+     * Retrieve context properties for given context ID.
+     *   
+     * @param id – context ID. 
+     * @param done - callback interface called when operation is completed.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client callback interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context data.
+         */
+        void doneGetContext(IToken token, Exception error, RunControlContext context);
+    }
+
+    /**
+     * Retrieve children of given context.
+     *   
+     * @param parent_context_id – parent context ID. Can be null –
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * @param done - callback interface called when operation is completed.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client callback interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service. 
+     */
+    interface RunControlContext {
+
+        /** 
+         * Retrieve context ID.
+         * Same as getProperties().get(“ID”)
+         */
+        String getID();
+
+        /** 
+         * Retrieve parent context ID.
+         * Same as getProperties().get(“ParentID”)
+         */
+        String getParentID();
+
+        /**
+         * Get context properties. See PROP_* definitions for property names.
+         * Context properties are read only, clients should not try to modify them.
+         * @return Map of context properties.
+         */
+        Map<String,Object> getProperties();
+
+        /**
+         * Utility method to read context property PROP_IS_CONTAINER.
+         * Executing resume or suspend command on a container causes all its children to resume or suspend.
+         * @return value of PROP_IS_CONTAINER.
+         */
+        boolean isContainer();
+        
+        /**
+         * Utility method to read context property PROP_HAS_STATE.
+         * Only context that has a state can be resumed or suspended. 
+         * @return value of PROP_HAS_STATE.
+         */
+        boolean hasState();
+        
+        /**
+         * Utility method to read context property PROP_CAN_SUSPEND.
+         * Value 'true' means suspend command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already suspended.
+         * @return value of PROP_CAN_SUSPEND.
+         */
+        boolean canSuspend();
+        
+        /**
+         * Utility method to read a 'mode' bit in context property PROP_CAN_RESUME.
+         * Value 'true' means resume command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already resumed.
+         * @param mode - resume mode, see RM_*. 
+         * @return value of requested bit of PROP_CAN_RESUME. 
+         */
+        boolean canResume(int mode);
+        
+        /**
+         * Utility method to read a 'mode' bit in context property PROP_CAN_COUNT.
+         * Value 'true' means resume command with count other then 1 is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already resumed.
+         * @param mode - resume mode, see RM_*. 
+         * @return value of requested bit of PROP_CAN_COUNT. 
+         */
+        boolean canCount(int mode);
+        
+        /**
+         * Utility method to read context property PROP_CAN_TERMINATE.
+         * Value 'true' means terminate command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already exited.
+         * @return value of PROP_CAN_SUSPEND.
+         */
+        boolean canTerminate();
+
+        /**
+         * Send a command to retrieve current state of a context.
+         * @param done - command result call back object.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken getState(DoneGetState done);
+
+        /**
+         * Send a command to suspend a context.
+         * Also suspends children if context is a container.
+         * @param done - command result call back object.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken suspend(DoneCommand done);
+        
+        /**
+         * Send a command to resume a context.
+         * Also resumes children if context is a container.
+         * @param mode - defines how to resume the context, see RM_*.
+         * @param count - if mode implies stepping, defines how many steps to perform.
+         * @param done - command result call back object.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken resume(int mode, int count, DoneCommand done);
+        
+        /**
+         * Send a command to resume a context.
+         * Also resumes children if context is a container.
+         * @param mode - defines how to resume the context, see RM_*.
+         * @param count - if mode implies stepping, defines how many steps to perform.
+         * @param params - resume parameters, for example, step range definition.
+         * @param done - command result call back object.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken resume(int mode, int count, Map<String,Object> params, DoneCommand done);
+        
+        /**
+         * Send a command to terminate a context.
+         * @param done - command result call back object.
+         * @return pending command handle, can be used to cancel the command.
+         */
+        IToken terminate(DoneCommand done);
+    }
+
+    class RunControlError extends Exception {
+
+        private static final long serialVersionUID = 1L;
+    }
+
+    interface DoneGetState {
+        void doneGetState(IToken token, Exception error, boolean suspended, String pc,
+                String reason, Map<String,Object> params);
+    }
+
+    interface DoneCommand {
+        /**
+         * Called when run control command execution is complete.
+         * @param token - pending command handle.
+         * @param error - command execution error or null.
+         */
+        void doneCommand(IToken token, Exception error);
+    }
+
+    /**
+     * Add run control event listener.
+     * @param listener - run control event listener to add.
+     */
+    void addListener(RunControlListener listener);
+    
+    /**
+     * Remove run control event listener.
+     * @param listener - run control event listener to remove.
+     */
+    void removeListener(RunControlListener listener);
+
+    /**
+     * Service events listener interface.
+     */
+    interface RunControlListener {
+
+        /**
+         * Called when new contexts are created.
+         * @param contexts - array of new context properties.
+         */
+        void contextAdded(RunControlContext contexts[]);
+
+        /**
+         * Called when a context properties changed.
+         * @param contexts - array of new context properties.
+         */
+        void contextChanged(RunControlContext contexts[]);
+
+        /**
+         * Called when contexts are removed.
+         * @param context_ids - array of removed context IDs.
+         */
+        void contextRemoved(String context_ids[]);
+
+        /**
+         * Called when a thread is suspended.
+         * @param context - ID of a context that was suspended.
+         * @param pc - program counter of the context, can be null.
+         * @param reason - human readable description of suspend reason.
+         * @param params - additional, target specific data about suspended context.
+         */
+        void contextSuspended(String context, String pc,
+                String reason, Map<String,Object> params);
+
+        /**
+         * Called when a thread is resumed.
+         * @param context - ID of a context that was resumed.
+         */
+        void contextResumed(String context);
+
+        /**
+         * Called when target simultaneously suspends multiple threads in a container
+         * (process, core, etc.).
+         * 
+         * @param context - ID of a context responsible for the event. It can be container ID or
+         * any one of container children, for example, it can be thread that hit "suspend all" breakpoint.
+         * Client expected to move focus (selection) to this context.
+         * @param pc - program counter of the context.
+         * @param reason - human readable description of suspend reason.
+         * @param params - additional target specific data about suspended context.
+         * @param suspended_ids - full list of all contexts that were suspended. 
+         */
+        void containerSuspended(String context, String pc,
+                String reason, Map<String,Object> params, String[] suspended_ids);
+
+        /**
+         * Called when target simultaneously resumes multiple threads in a container (process,
+         * core, etc.).
+         * 
+         * @param context_ids - full list of all contexts that were resumed. 
+         */
+        void containerResumed(String[] context_ids);
+
+        /**
+         * Called when an exception is detected in a target thread.
+         * @param context - ID of a context that caused an exception.
+         * @param msg - human readable description of the exception.
+         */
+        void contextException(String context, String msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IStackTrace.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+public interface IStackTrace extends IService {
+
+    static final String NAME = "StackTrace";
+
+    /**
+     * Context property names.
+     */
+    static final String
+        PROP_ID = "ID",
+        PROP_PARENT_ID = "ParentID",
+        PROP_PROCESS_ID = "ProcessID",
+        PROP_NAME = "Name",
+        PROP_FRAME_ADDRESS = "FP",
+        PROP_RETURN_ADDRESS = "RP",
+        PROP_INSTRUCTION_ADDRESS = "IP", 
+        PROP_ARGUMENTS_COUNT = "ArgsCnt",
+        PROP_ARGUMENTS_ADDRESS = "ArgsAddr";
+
+    /**
+     * Retrieve context info for given context IDs.
+     * 
+     * The command will fail if parent thread is not suspended.
+     * Client can use Run Control service to suspend a thread.
+     *   
+     * @param id – array of context IDs. 
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getContext(String[] id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – array of context data or null if error.
+         */
+        void doneGetContext(IToken token, Exception error, StackTraceContext[] context);
+    }
+
+    /**
+     * Retrieve stack trace context list.
+     * Parent context usually corresponds to an execution thread.
+     * Some targets have more then one stack. In such case children of a thread
+     * are stacks, and stack frames are deeper in the hierarchy - they can be
+     * retrieved with additional getChildren commands.
+     * 
+     * The command will fail if parent thread is not suspended.
+     * Client can use Run Control service to suspend a thread.
+     *  
+     * @param parent_context_id – parent context ID.
+     * @param done - call back interface called when operation is completed.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         * Stack frames are ordered from stack bottom to top.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * StackTraceContext represents stack trace objects - stacks and stack frames. 
+     */
+    interface StackTraceContext {
+        
+        /**
+         * Get Context ID.
+         * @return context ID.
+         */
+        String getID();
+        
+        /**
+         * Get parent context ID.
+         * @return parent context ID.
+         */
+        String getParentID();
+        
+        /**
+         * Get context name - if context represents a stack.
+         * @return context name or null.
+         */
+        String getName();
+        
+        /**
+         * Get memory address of this frame.
+         * @return address or null if not a stack frame.
+         */
+        Number getFrameAddress();
+        
+        /**
+         * Get program counter saved in this stack frame -
+         * it is address of instruction to be executed when the function returns.
+         * @return return address or null if not a stack frame.
+         */
+        Number getReturnAddress();
+        
+        /**
+         * Get address of the next instruction to be executed in this stack frame.
+         * For top frame it is same as PC register value.
+         * For other frames it is same as return address of the next frame.
+         * @return instruction address or null if not a stack frame.
+         */
+        Number getInstructionAddress();
+        
+        /**
+         * Get number of function arguments for this frame.
+         * @return function arguments count.
+         */
+        int getArgumentsCount();
+        
+        /**
+         * Get address of function arguments area in memory.
+         * @return function arguments address or null if not available.
+         */
+        Number getArgumentsAddress();
+        
+        /**
+         * Get complete map of context properties.
+         * @return map of context properties.
+         */
+        Map<String,Object> getProperties();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IStreams.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+/**
+ * Streams service is a generic interface to support streaming of data between host and remote agents.
+ * 
+ * The service supports:
+ *  1. Asynchronous overlapped data streaming: multiple 'read' or 'write' command can be issued at same time, both peers
+ *  can continue data processing concurrently with data transmission.
+ *  2. Multicast: multiple clients can receive data from same stream.
+ *  3. Subscription model: clients are required to expressed interest in particular streams by subscribing for the service.
+ *  4. Flow control: peers can throttle data flow of individual streams by delaying 'read' and 'write' commands.   
+ */
+public interface IStreams extends IService {
+
+    /**
+     * Service name.
+     */
+    static final String NAME = "Streams";
+
+    /**
+     * Clients can implement StreamsListener interface to be notified
+     * when a stream is created or disposed. The interface is registered with 'subscribe' command. 
+     * 
+     * When new stream is created, client must decide if it is interested in that particular stream instance.
+     * If not interested, client should send 'disconnect' command to allow remote peer to free resources and bandwidth.
+     * If not disconnected, client is required to send 'read' commands as necessary to prevent stream buffer overflow.
+     */
+    interface StreamsListener {
+
+        /**
+         * Called when a new stream is created. 
+         * @param stream_type - source type of the stream.
+         * @param stream_id - ID of the stream.
+         * @param context_id - a context ID that is associated with the stream, or null.
+         * Exact meaning of the context ID depends on stream type.
+         * Stream types and context IDs are defined by services that use Streams service to transmit data.
+         */
+        void created(String stream_type, String stream_id, String context_id);
+
+        /**
+         * Called when a stream is disposed. 
+         * @param stream_type - source type of the stream.
+         * @param stream_id - ID of the stream.
+         */
+        void disposed(String stream_type, String stream_id);
+    }
+
+    /**
+     * Clients must subscribe for one or more stream types to be able to send or receive stream data.
+     * Subscribers receive notifications when a stream of given type is created or disposed.
+     * Subscribers are required to respond with 'read' or 'disconnect' commands as necessary.
+     * @param stream_type - the stream source type.
+     * @param listener - client implementation of StreamsListener interface.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken subscribe(String stream_type, StreamsListener listener, DoneSubscribe done);
+
+    /**
+     * Call back interface for 'subscribe' command.
+     */
+    interface DoneSubscribe {
+        void doneSubscribe(IToken token, Exception error);
+    }
+
+    /**
+     * Unsubscribe the client from given stream source type.
+     * @param stream_type - the stream source type.
+     * @param listener - client implementation of StreamsListener interface.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken unsubscribe(String stream_type, StreamsListener listener, DoneUnsubscribe done);
+
+    /**
+     * Call back interface for 'unsubscribe' command.
+     */
+    interface DoneUnsubscribe {
+        void doneUnsubscribe(IToken token, Exception error);
+    }
+
+    /**
+     * Read data from a stream. If stream buffer is empty, the command will wait until data is available.
+     * Remote peer will continue to process other commands while 'read' command is pending.
+     * Client can send more 'read' commands without waiting for the first command to complete.
+     * Doing that improves communication channel bandwidth utilization.
+     * Pending 'read' commands will be executed in same order as issued.
+     * Client can delay sending of 'read' command if it is not ready to receive more data,
+     * however, delaying for too long can cause stream buffer overflow and lost of data.
+     * @param stream_id - ID of the stream.
+     * @param size - max number of bytes to read.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken read(String stream_id, int size, DoneRead done);
+
+    /**
+     * Call back interface for 'read' command.
+     */
+    interface DoneRead {
+        /**
+         * Called when 'read' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         * @param lost_size - number of bytes that were lost because of buffer overflow.
+         * 'lost_size' -1 means unknown number of bytes were lost.
+         * if both 'lost_size' and 'data.length' are non-zero then lost bytes are considered
+         * located right before read bytes. 
+         * @param data - bytes read from the stream.
+         * @param eos - true if end of stream was reached.
+         */
+        void doneRead(IToken token, Exception error, int lost_size, byte[] data, boolean eos);
+    }
+
+    /**
+     * Write data to a stream. If stream buffer is full, the command will wait until space is available.
+     * Remote peer will continue to process other commands while 'write' command is pending.
+     * Client can send more 'write' commands without waiting for the first command to complete.
+     * Doing that improves communication channel bandwidth utilization.
+     * Pending 'write' commands will be executed in same order as issued.
+     * @param stream_id - ID of the stream.
+     * @param buf - buffer that contains stream data.
+     * @param offset - byte offset in the buffer.
+     * @param size - number of bytes to write.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken write(String stream_id, byte[] buf, int offset, int size, DoneWrite done);
+
+    /**
+     * Call back interface for 'write' command.
+     */
+    interface DoneWrite {
+        /**
+         * Called when 'write' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneWrite(IToken token, Exception error);
+    }
+
+    /**
+     * Send End Of Stream marker to a stream. No more writing to the stream is allowed after that. 
+     * @param stream_id - ID of the stream.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken eos(String stream_id, DoneEOS done);
+
+    /**
+     * Call back interface for 'eos' command.
+     */
+    interface DoneEOS {
+        /**
+         * Called when 'eos' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneEOS(IToken token, Exception error);
+    }
+
+    /**
+     * Connect client to a stream.
+     * Some data might be dropped from the stream by the time "connect" command is executed.
+     * Client should be able to re-sync with stream data if it wants to read from such stream.
+     * If a client wants to read a stream from the beginning it should use "subscribe" command
+     * instead of "connect".
+     * @param stream_id - ID of the stream.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken connect(String stream_id, DoneConnect done);
+
+    /**
+     * Call back interface for 'connect' command.
+     */
+    interface DoneConnect {
+        /**
+         * Called when 'connect' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneConnect(IToken token, Exception error);
+    }
+
+    /**
+     * Disconnect client from a stream.
+     * @param stream_id - ID of the stream.
+     * @param done - command result call back object.
+     * @return - pending command handle.
+     */
+    IToken disconnect(String stream_id, DoneDisconnect done);
+
+    /**
+     * Call back interface for 'disconnect' command.
+     */
+    interface DoneDisconnect {
+        /**
+         * Called when 'disconnect' command is done.
+         * @param token - command handle.
+         * @param error - error object or null.
+         */
+        void doneDisconnect(IToken token, Exception error);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+public interface ISymbols extends IService {
+
+    /**
+     * Service name.
+     */
+    static final String NAME = "Symbols";
+    
+    enum SymbolClass {
+        unknown,                // unknown symbol class
+        value,                  // constant value
+        reference,              // variable data object
+        function,               // function body
+        type                    // a type
+    }
+    
+    enum TypeClass {
+        unknown,                // unknown type class
+        cardinal,               // unsigned integer
+        integer,                // signed integer
+        real,                   // float, double
+        pointer,                // pointer to anything.
+        array,                  // array of anything.
+        composite,              // struct, union, or class.
+        enumeration,            // enumeration type.
+        function                // function type.
+    }
+    
+    /**
+     * Symbol context interface.
+     */
+    interface Symbol {
+        /**
+         * Get symbol ID.
+         * @return symbol ID.
+         */
+        String getID();
+        
+        /**
+         * Get execution context ID (thread or process) that owns this instance of a symbol.
+         * @return execution context ID.
+         */
+        String getExeContextID();
+        
+        /**
+         * Get symbol name.
+         * @return symbol name or null.
+         */
+        String getName();
+        
+        /**
+         * Get symbol class.
+         * @return symbol class.
+         */
+        SymbolClass getSymbolClass();
+        
+        /**
+         * Get symbol type class.
+         * @return type class.
+         */
+        TypeClass getTypeClass();
+        
+        /**
+         * Get type ID.
+         * If the symbol is a type and not a 'typedef', return same as getID(). 
+         * @return type ID.
+         */
+        String getTypeID();
+        
+        /**
+         * Get base type ID.
+         * If this symbol is a
+         *   pointer type - return pointed type;
+         *   array type - return element type;
+         *   function type - return function result type;
+         *   class type - return base class;
+         * otherwise return null.  
+         * @return type ID.
+         */
+        String getBaseTypeID();
+        
+        /**
+         * Get index type ID.
+         * If this symbol is a
+         *   array type - return array index type;
+         * otherwise return null.  
+         * @return type ID.
+         */
+        String getIndexTypeID();
+        
+        /**
+         * Return value size of the symbol (or type).
+         * @return size in bytes.
+         */
+        int getSize();
+        
+        /**
+         * If symbol is an array type - return number of elements. 
+         * @return number of elements.
+         */
+        int getLength();
+        
+        /**
+         * Return offset from 'this' for member of class, struct or union.
+         * @return offset in bytes.
+         */
+        int getOffset();
+        
+        /**
+         * Return address of the symbol.
+         * @return address or null.
+         */
+        Number getAddress();
+        
+        /**
+         * If symbol is a constant object, return its value. 
+         * @return symbol value as array of bytes.
+         */
+        byte[] getValue();
+
+        /**
+         * Get complete map of context properties.
+         * @return map of context properties.
+         */
+        Map<String,Object> getProperties();
+    }
+
+    /**
+     * Symbol context property names.
+     */
+    static final String
+        PROP_ID = "ID",
+        PROP_EXE_ID = "ExeID",
+        PROP_NAME = "Name",
+        PROP_SYMBOL_CLASS = "Class",
+        PROP_TYPE_CLASS = "TypeClass",
+        PROP_TYPE_ID = "TypeID",
+        PROP_BASE_TYPE_ID = "BaseTypeID",
+        PROP_INDEX_TYPE_ID = "IndexTypeID",
+        PROP_SIZE = "Size",
+        PROP_LENGTH = "Length",
+        PROP_OFFSET = "Offset",
+        PROP_ADDRESS = "Address",
+        PROP_VALUE = "Value";
+
+    /**
+     * Retrieve symbol context info for given symbol ID.
+     * @see Symbol
+     *   
+     * @param id – symbol context ID. 
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client call back interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context properties.
+         */
+        void doneGetContext(IToken token, Exception error, Symbol context);
+    }
+
+    /**
+     * Retrieve children IDs for given parent ID.
+     * Meaning of the operation depends on parent kind:
+     * 1. struct, union, or class type - get fields; 
+     * 2. enumeration type - get enumerators;
+     * 
+     * @param parent_context_id – parent symbol context ID.
+     * @param done - call back interface called when operation is completed.
+     * @return - pending command handle.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client call back interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param token - command handle
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISysMonitor.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.services;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+
+
+/**
+ * This is optional service that can be implemented by a peer. 
+ * If implemented, the service can be used for monitoring system activity and utilization.
+ * It provides list of running processes, different process attributes like command line, environment, etc.,
+ * and some resource utilization data. The service can be used by a client to provide functionality
+ * similar to Unix 'top' utility or Windows 'Task Manager'.
+ */
+public interface ISysMonitor extends IService {
+
+   static final String NAME = "SysMonitor";
+
+    /**
+     * Retrieve context info for given context ID.
+     *   
+     * @param id – context ID. 
+     * @param done - callback interface called when operation is completed.
+     */
+    IToken getContext(String id, DoneGetContext done);
+
+    /**
+     * Client callback interface for getContext().
+     */
+    interface DoneGetContext {
+        /**
+         * Called when context data retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context – context data.
+         */
+        void doneGetContext(IToken token, Exception error, SysMonitorContext context);
+    }
+
+    /**
+     * Retrieve children of given context.
+     *   
+     * @param parent_context_id – parent context ID. Can be null –
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * @param done - callback interface called when operation is completed.
+     */
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    /**
+     * Client callback interface for getChildren().
+     */
+    interface DoneGetChildren {
+        /**
+         * Called when context list retrieval is done.
+         * @param error – error description if operation failed, null if succeeded.
+         * @param context_ids – array of available context IDs.
+         */
+        void doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    /**
+     * Context property names.
+     */
+    static final String
+        /** The TCF context ID */
+        PROP_ID = "ID",
+        
+        /** The TCF parent context ID */
+        PROP_PARENTID = "ParentID",
+        
+        /** Current working directory of the process */
+        PROP_CWD = "CWD",
+        
+        /** The process's root directory (as set by chroot) */
+        PROP_ROOT = "Root",
+        
+        /** User ID of the process owner */
+        PROP_UID = "UID",
+        
+        /** Group ID of the process owner */
+        PROP_UGID = "UGID",
+        
+        /** User name of the process owner */
+        PROP_USERNAME = "UserName",
+        
+        /** Group name of the process owner */
+        PROP_GROUPNAME = "GroupName",
+        
+        /** System process ID */
+        PROP_PID = "PID",
+        
+        /** Executable file of the process */
+        PROP_FILE = "File",
+        
+        /** One character from the string "RSDZTW"  where  R  is  running,  S  is
+         *  sleeping  in  an  interruptible wait, D is waiting in uninterruptible
+         *  disk sleep, Z is zombie, T is traced or stopped (on a signal), and  W
+         *  is paging.*/
+        PROP_STATE = "State",
+        
+        /** System ID of the parent process */
+        PROP_PPID = "PPID",
+        
+        /** The process group ID of the process */
+        PROP_PGRP = "PGRP",
+        
+        /** The session ID of the process */
+        PROP_SESSION = "Session",
+        
+        /** The tty the process uses */
+        PROP_TTY = "TTY",
+        
+        /** The process group ID of the process which currently owns the tty that
+         *  the process is connected to. */
+        PROP_TGID = "TGID",
+        
+        /** ID of a process that has attached this process for tracing or debugging */
+        PROP_TRACERPID = "TracerPID",
+        
+        /** The kernel flags word of the process. Details depend on the kernel */
+        PROP_FLAGS = "Flags",
+        
+        /** The  number  of  minor  faults  the  process  has made which have not
+         *  required loading a memory page from disk */
+        PROP_MINFLT = "MinFlt",
+        
+        /** The number of minor faults that  the  process's  waited-for  children have made */
+        PROP_CMINFLT = "CMinFlt",       
+        
+        /** The  number  of major faults the process has made which have required
+         *  loading a memory page from disk */
+        PROP_MAJFLT = "MajFlt",
+        
+        /** The number of major faults that  the  process's  waited-for  children
+         *  have made */
+        PROP_CMAJFLT = "CMajFlt",
+        
+        /** The number of milliseconds that this process has been scheduled in user mode */
+        PROP_UTIME = "UTime",
+        
+        /** The number of milliseconds that this process has been scheduled in kernel mode */
+        PROP_STIME = "STime",
+        
+        /** The  number  of  jiffies that this process's waited-for children have
+         *  been scheduled in user mode */
+        PROP_CUTIME = "CUTime",
+        
+        /** The  number  of  jiffies that this process's waited-for children have
+         *  been scheduled in user mode */
+        PROP_CSTIME = "CSTime",
+        
+        /** The standard nice value */
+        PROP_PRIORITY = "Priority",
+        
+        /** The nice value */
+        PROP_NICE = "Nice",
+        
+        /** The time in milliseconds before the next SIGALRM is sent  to  the  process
+         *  due to an interval timer */
+        PROP_ITREALVALUE = "ITRealValue",
+        
+        /** The time in milliseconds the process started after system boot */
+        PROP_STARTTIME = "StartTime",
+        
+        /** Virtual memory size in bytes */
+        PROP_VSIZE = "VSize",
+        
+        /** Memory pages size in bytes */
+        PROP_PSIZE = "PSize",
+        
+        /** Resident  Set  Size:  number of pages the process has in real memory,
+         *  minus used for administrative purposes. This is  just  the  pages  which
+         *  count  towards  text,  data,  or  stack space.  This does not include
+         *  pages which have not been demand-loaded in, or which are swapped out */
+        PROP_RSS = "RSS",
+        
+        /** Current  limit in bytes on the rss of the process */
+        PROP_RLIMIT = "RLimit",
+        
+        /** The address above which program text can run */
+        PROP_CODESTART = "CodeStart",
+        
+        /** The address below which program text can run */
+        PROP_CODEEND = "CodeEnd",
+        
+        /** The address of the start of the stack */
+        PROP_STACKSTART = "StackStart",
+        
+        /** The bitmap of pending signals */
+        PROP_SIGNALS = "Signals",
+        
+        /** The bitmap of blocked signals */
+        PROP_SIGBLOCK = "SigBlock",
+        
+        /** The bitmap of ignored signals */
+        PROP_SIGIGNORE = "SigIgnore",
+        
+        /** The bitmap of caught signals */
+        PROP_SIGCATCH = "SigCatch",
+        
+        /** This  is  the  "channel"  in which the process is waiting.  It is the
+         *  address of a system call, and can be looked up in a name list  if  you
+         *  need  a  textual  name */
+        PROP_WCHAN = "WChan",
+        
+        /** Number of pages swapped */
+        PROP_NSWAP = "NSwap",
+        
+        /** Cumulative NSwap for child processes */
+        PROP_CNSWAP = "CNSwap",
+        
+        /** Signal to be sent to parent when this process exits */
+        PROP_EXITSIGNAL = "ExitSignal",
+        
+        /** CPU number last executed on */
+        PROP_PROCESSOR = "Processor",
+        
+        /** Real-time scheduling priority */
+        PROP_RTPRIORITY = "RTPriority",
+        
+        /** Scheduling policy */
+        PROP_POLICY = "Policy";
+
+
+    /**
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service. 
+     */
+    interface SysMonitorContext {
+
+        /** 
+         * Get context ID.
+         * Same as getProperties().get(“ID”)
+         */
+        String getID();
+
+        /** 
+         * Get parent context ID.
+         * Same as getProperties().get(“ParentID”)
+         */
+        String getParentID();
+
+        /** 
+         * Get process group ID.
+         * Same as getProperties().get(“PGRP”)
+         */
+        long getPGRP();
+
+        /** 
+         * Get process ID.
+         * Same as getProperties().get(“PID”)
+         */
+        long getPID();
+
+        /** 
+         * Get process parent ID.
+         * Same as getProperties().get(“PPID”)
+         */
+        long getPPID();
+
+        /** 
+         * Get process TTY group ID.
+         * Same as getProperties().get(“TGID”)
+         */
+        long getTGID();
+
+        /** 
+         * Get tracer process ID.
+         * Same as getProperties().get(“TracerPID”)
+         */
+        long getTracerPID();
+
+        /** 
+         * Get process owner user ID.
+         * Same as getProperties().get(“UID”)
+         */
+        long getUID();
+
+        /** 
+         * Get process owner user name.
+         * Same as getProperties().get(“UserName”)
+         */
+        String getUserName();
+
+        /** 
+         * Get process owner user group ID.
+         * Same as getProperties().get(“UGID”)
+         */
+        long getUGID();
+
+        /** 
+         * Get process owner user group name.
+         * Same as getProperties().get(“GroupName”)
+         */
+        String getGroupName();
+        
+        /** 
+         * Get process state.
+         * Same as getProperties().get(“State”)
+         */
+        String getState();
+
+        /** 
+         * Get process virtual memory size in bytes.
+         * Same as getProperties().get(“VSize”)
+         */
+        long getVSize();
+
+        /** 
+         * Get process virtual memory page size in bytes.
+         * Same as getProperties().get(“PSize”)
+         */
+        long getPSize();
+
+        /** 
+         * Get number of memory pages in process resident set.
+         * Same as getProperties().get(“RSS”)
+         */
+        long getRSS();
+
+        /** 
+         * Get context executable file.
+         * Same as getProperties().get(“File”)
+         */
+        String getFile();
+
+        /** 
+         * Get context current file system root.
+         * Same as getProperties().get(“Root”)
+         */
+        String getRoot();
+
+        /** 
+         * Get context current working directory.
+         * Same as getProperties().get(“CWD”)
+         */
+        String getCurrentWorkingDirectory();
+
+        /**
+         * Get all available context properties.
+         * @return Map 'property name' -> 'property value'
+         */
+        Map<String,Object> getProperties();
+    }
+    
+    /** 
+     * Get context command line.
+     */
+    IToken getCommandLine(String id, DoneGetCommandLine done);
+    
+    interface DoneGetCommandLine {
+        void doneGetCommandLine(IToken token, Exception error, String[] cmd_line);
+    }
+
+    /** 
+     * Get context environment variables.
+     */
+    IToken getEnvironment(String id, DoneGetEnvironment done);
+    
+    interface DoneGetEnvironment {
+        void doneGetEnvironment(IToken token, Exception error, String[] environment);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.util;
+
+import java.util.HashSet;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * Objects of this class are used to cache TCF remote data.
+ * The cache is asynchronous state machine. The states are:
+ *  1. Valid - cache is in sync with remote data, use getError() and getData() to get cached data;
+ *  2. Invalid - cache is out of sync, start data retrieval by calling validate();
+ *  3. Pending - cache is waiting result of a command that was sent to remote peer.
+ * @param <V> - type of data to be stored in the cache.
+ */
+public abstract class TCFDataCache<V> implements Runnable {
+
+    private Throwable error;
+    private boolean valid;
+    private boolean posted;
+    private V data;
+    
+    protected final IChannel channel;
+    protected IToken command;
+
+    private final HashSet<Runnable> waiting_list = new HashSet<Runnable>();
+    
+    public TCFDataCache(IChannel channel) {
+        assert channel != null;
+        this.channel = channel;
+    }
+    
+    private void post() {
+        if (posted) return;
+        if (waiting_list.isEmpty()) return;
+        Protocol.invokeLater(this);
+        posted = true;
+    }
+    
+    /**
+     * @return true if cache contains up-to-date data (or data retrieval error).
+     */
+    public boolean isValid() {
+        return valid;
+    }
+    
+    /**
+     * @return true if data retrieval command is in progress.
+     */
+    public boolean isPending() {
+        return command != null;
+    }
+    
+    /**
+     * @return error object if data retrieval ended with an error, or null if retrieval was successful.
+     * Note: It is prohibited to call this method when cache is not valid. 
+     */
+    public Throwable getError() {
+        assert valid;
+        return error;
+    }
+    
+    /**
+     * @return cached data object.
+     * Note: It is prohibited to call this method when cache is not valid. 
+     */
+    public V getData() {
+        assert Protocol.isDispatchThread();
+        assert valid;
+        return data;
+    }
+    
+    /**
+     * Notify waiting clients about cache state change and remove them from wait list.
+     * It is responsibility of clients to check if the state change was one they are waiting for.
+     */
+    public void run() {
+        assert Protocol.isDispatchThread();
+        posted = false;
+        Runnable[] arr = waiting_list.toArray(new Runnable[waiting_list.size()]);
+        waiting_list.clear();
+        for (Runnable r : arr) {
+            if (r instanceof TCFDataCache<?> && ((TCFDataCache<?>)r).posted) continue;
+            r.run();
+        }
+    }
+    
+    /**
+     * Add a client call-back to cache wait list.
+     * Client call-backs are activated when cache state changes.
+     * Call-backs are removed from waiting list after that.
+     * It is responsibility of clients to check if the state change was one they are waiting for.
+     * @param cb - a call-back object
+     */
+    public void wait(Runnable cb) {
+        assert Protocol.isDispatchThread();
+        assert !valid;
+        if (cb != null) waiting_list.add(cb);
+    }
+    
+    /**
+     * Initiate data retrieval if the cache is not valid.
+     * @return true if the cache is already valid
+     */
+    public boolean validate() {
+        assert Protocol.isDispatchThread();
+        if (channel.getState() != IChannel.STATE_OPEN) {
+            error = null;
+            command = null;
+            valid = true;
+            data = null;
+        }
+        else {
+            if (command != null) return false;
+            if (!valid && !startDataRetrieval()) return false;
+        }
+        assert valid;
+        assert command == null;
+        post();
+        return true;
+    }
+    
+    /**
+     * End cache pending state.
+     * @param token - pending command handle.
+     * @param error - data retrieval error or null
+     * @param data - up-to-date data object
+     */
+    public void set(IToken token, Throwable error, V data) {
+        assert Protocol.isDispatchThread();
+        if (command != token) return;
+        command = null;
+        if (channel.getState() != IChannel.STATE_OPEN) data = null;
+        this.error = error;
+        this.data = data;
+        valid = true;
+        post();
+    }
+
+    /**
+     * Force cache to become valid, cancel pending data retrieval if any.
+     * @param data - up-to-date data object
+     */
+    public void reset(V data) {
+        assert Protocol.isDispatchThread();
+        if (command != null) {
+            command.cancel();
+            command = null;
+        }
+        this.data = data;
+        error = null;
+        valid = true;
+        post();
+    }
+    
+    /**
+     * Invalidate the cache. If retrieval is in progress - let it continue.
+     */
+    public void reset() {
+        assert Protocol.isDispatchThread();
+        error = null;
+        valid = false;
+        data = null;
+        post();
+    }
+    
+    /**
+     * Force cache to invalid state, cancel pending data retrieval if any.
+     */
+    public void cancel() {
+        assert Protocol.isDispatchThread();
+        if (command != null) {
+            command.cancel();
+            command = null;
+        }
+        error = null;
+        valid = false;
+        data = null;
+        post();
+    }
+    
+    @Override
+    public String toString() {
+        StringBuffer bf = new StringBuffer();
+        bf.append('[');
+        if (valid) bf.append("valid,");
+        if (posted) bf.append("posted,");
+        if (error != null) bf.append("error,");
+        bf.append("data=");
+        bf.append(data == null ? "null" : data.toString());
+        bf.append(']');
+        return bf.toString();
+    }
+    
+    /**
+     * Sub-classes should override this method to implement actual data retrieval logic.
+     * @return true is all done, false if retrieval is in progress.
+     */
+    protected abstract boolean startDataRetrieval();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFFileInputStream.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IFileSystem;
+import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tm.tcf.services.IFileSystem.IFileHandle;
+
+/**
+ * TCFFileInputStream is high performance InputStream implementation over TCF FileSystem service.
+ * The class uses read-ahead buffers to achieve maximum throughput.
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public final class TCFFileInputStream extends InputStream {
+    
+    private static final int MAX_READ_AHEAD = 8;
+    
+    private static class Buffer {
+        
+        final long offset;
+
+        IToken token;
+        byte[] buf;
+        boolean eof;
+
+        Buffer(long offset) {
+            this.offset = offset;
+        }
+        
+        @Override
+        public String toString() {
+            return "[" + offset + ":" + (buf == null ? "null" : Integer.toString(buf.length)) + "]";
+        }
+    }
+    
+    private final IFileHandle handle;
+    private final IFileSystem fs;
+    private final int buf_size;
+    private long mark = 0;
+    private long offset = 0;
+    private Buffer buf;
+    private boolean closed = false;
+    
+    private boolean suspend_read_ahead;
+    private Runnable waiting_client;
+    private final LinkedList<Buffer> read_ahead_buffers = new LinkedList<Buffer>();
+    
+    public TCFFileInputStream(IFileHandle handle) {
+        this(handle, 0x1000);
+    }
+
+    public TCFFileInputStream(IFileHandle handle, int buf_size) {
+        this.handle = handle;
+        this.fs = handle.getService();
+        this.buf_size = buf_size;
+    }
+    
+    private void startReadAhead(Buffer prv) {
+        if (suspend_read_ahead) return;
+        if (read_ahead_buffers.size() > 0) {
+            prv = read_ahead_buffers.getLast();
+        }
+        if (prv.eof) return;
+        long pos = prv.offset + (prv.buf == null ? buf_size : prv.buf.length);
+        while (read_ahead_buffers.size() < MAX_READ_AHEAD) {
+            final Buffer buf = new Buffer(pos);
+            buf.token = fs.read(handle, pos, buf_size, new IFileSystem.DoneRead() {
+                public void doneRead(IToken token, FileSystemException error,
+                        byte[] data, boolean eof) {
+                    assert buf.token == token;
+                    assert read_ahead_buffers.contains(buf);
+                    buf.token = null;
+                    if (error != null) {
+                        suspend_read_ahead = true;
+                        read_ahead_buffers.remove(buf);
+                    }
+                    else if (data.length != buf_size) {
+                        buf.buf = data;
+                        buf.eof = eof;
+                        if (!eof) suspend_read_ahead = true;
+                    }
+                    else {
+                        buf.buf = data;
+                        buf.eof = eof;
+                        startReadAhead(buf);
+                    }
+                    if (waiting_client != null) {
+                        Protocol.invokeLater(waiting_client);
+                        waiting_client = null;
+                    }
+                }
+            });
+            read_ahead_buffers.add(buf);
+            pos += buf_size;
+        }
+    }
+    
+    private boolean stopReadAhead(Runnable done) {
+        suspend_read_ahead = true;
+        for (Iterator<Buffer> i = read_ahead_buffers.iterator(); i.hasNext();) {
+            Buffer buf = i.next();
+            if (buf.token == null || buf.token.cancel()) i.remove();
+        }
+        if (read_ahead_buffers.size() > 0) {
+            assert waiting_client == null;
+            waiting_client = done;
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public synchronized int read() throws IOException {
+        if (closed) throw new IOException("Stream is closed");
+        while (buf == null || buf.offset > offset || buf.offset + buf.buf.length <= offset) {
+            if (buf != null && buf.eof) return -1;
+            buf = new TCFTask<Buffer>() {
+                public void run() {
+                    assert waiting_client == null;
+                    while (read_ahead_buffers.size() > 0) {
+                        Buffer buf = read_ahead_buffers.getFirst();
+                        if (buf.offset == offset) {
+                            if (buf.token != null) {
+                                waiting_client = this;
+                            }
+                            else {
+                                startReadAhead(buf);
+                                read_ahead_buffers.remove(buf);
+                                done(buf);
+                            }
+                            return;
+                        }
+                        suspend_read_ahead = true;
+                        if (buf.token != null && buf.token.cancel()) buf.token = null;
+                        if (buf.token != null) {
+                            waiting_client = this;
+                            return;
+                        }
+                        read_ahead_buffers.remove(buf);
+                    }
+                    fs.read(handle, offset, buf_size, new IFileSystem.DoneRead() {
+                        public void doneRead(IToken token, FileSystemException error,
+                                byte[] data, boolean eof) {
+                            if (error != null) {
+                                error(error);
+                                return;
+                            }
+                            assert data != null && data.length <= buf_size;
+                            Buffer buf = new Buffer(offset);
+                            buf.buf = data;
+                            buf.eof = eof;
+                            if (!eof) {
+                                suspend_read_ahead = false;
+                                startReadAhead(buf);
+                            }
+                            done(buf);
+                        }
+                    });
+                }
+            }.getIO();
+            assert buf.token == null;
+        }
+        int ofs = (int)(offset++ - buf.offset);
+        return buf.buf[ofs] & 0xff;
+    }
+
+    @Override
+    public synchronized int read(final byte arr[], final int off, final int len) throws IOException {
+        if (closed) throw new IOException("Stream is closed");
+        if (arr == null) throw new NullPointerException();
+        if (off < 0 || len < 0 || len > arr.length - off) throw new IndexOutOfBoundsException();
+        int pos = 0;
+        while (pos < len) {
+            if (buf != null && buf.offset <= offset && buf.offset + buf.buf.length > offset) {
+                int buf_pos = (int)(offset - buf.offset);
+                int buf_len = buf.buf.length - buf_pos;
+                int n = len - pos < buf_len ? len - pos : buf_len;
+                System.arraycopy(buf.buf, buf_pos, arr, off + pos, n);
+                pos += n;
+                offset += n;
+            }
+            else {
+                int c = read();
+                if (c == -1) {
+                    if (pos == 0) return -1;
+                    break;
+                }
+                arr[off + pos++] = (byte)c;
+            }
+        }
+        return pos;
+    }
+    
+    @Override
+    public boolean markSupported() {
+        return true;
+    }
+
+    @Override
+    public synchronized void reset() throws IOException {
+        if (closed) throw new IOException("Stream is closed");
+        offset = mark;
+        if (buf != null && buf.offset <= offset && buf.offset + buf.buf.length > offset) return;
+        new TCFTask<Object>() {
+            public void run() {
+                if (!stopReadAhead(this)) return;
+                done(this);
+            }
+        }.getIO();
+        buf = null;
+    }
+
+    @Override
+    public synchronized void mark(int readlimit) {
+        mark = offset;
+    }
+
+    @Override
+    public synchronized void close() throws IOException {
+        if (closed) return;
+        new TCFTask<Object>() {
+            public void run() {
+                if (!stopReadAhead(this)) return;
+                assert read_ahead_buffers.isEmpty();
+                fs.close(handle, new IFileSystem.DoneClose() {
+                    public void doneClose(IToken token, FileSystemException error) {
+                        if (error != null) error(error);
+                        else done(this);
+                    }
+                });
+            }
+        }.getIO();
+        closed = true;
+        buf = null;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFFileOutputStream.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.util;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IFileSystem;
+import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tm.tcf.services.IFileSystem.IFileHandle;
+
+/**
+ * TCFFileOutputStream is high performance OutputStream implementation over TCF FileSystem service.
+ * The class uses write-back buffers to achieve maximum throughput.
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public final class TCFFileOutputStream extends OutputStream {
+    
+    private static final int MAX_WRITE_BACK = 8;
+
+    private final IFileHandle handle;
+    private final IFileSystem fs;
+    private final int buf_size;
+    private final Set<IToken> write_commands = new HashSet<IToken>();
+    private final int[] dirty = new int[1];
+    private final byte[] buf;
+    private int buf_pos = 0;
+    private long offset = 0;
+    private IOException flush_error;
+    private boolean closed;
+
+    public TCFFileOutputStream(IFileHandle handle) {
+        this(handle, 0x1000);
+    }
+    
+    public TCFFileOutputStream(IFileHandle handle, int buf_size) {
+        this.handle = handle;
+        this.fs = handle.getService();
+        this.buf_size = buf_size;
+        buf = new byte[buf_size];
+    }
+
+    @Override
+    public synchronized void write(int b) throws IOException {
+        if (closed) throw new IOException("Stream is closed");
+        if (buf_pos == buf_size) flush();
+        buf[buf_pos++] = (byte)b;
+    }
+
+    @Override
+    public void write(byte b[], int off, int len) throws IOException {
+        if (len == 0) return;
+        if (b == null) throw new NullPointerException();
+        if (off < 0 || off > b.length || len < 0 ||
+                   off + len > b.length || off + len < 0)
+            throw new IndexOutOfBoundsException();
+        while (len > 0) {
+            if (buf_pos == buf_size) flush();
+            if (buf_pos == 0 && len > buf_size) {
+                flush(b, off, len);
+                return;
+            }
+            int n = buf_size - buf_pos;
+            if (len < n) n = len;
+            System.arraycopy(b, off, buf, buf_pos, n);
+            off += n;
+            len -= n;
+            buf_pos += n;
+        }
+    }
+
+    @Override
+    public synchronized void flush() throws IOException {
+        if (buf_pos == 0) return;
+        flush(buf, 0, buf_pos);
+        buf_pos = 0;
+    }
+    
+    private void flush(final byte[] buf, final int off, final int len) throws IOException {
+        synchronized (dirty) {
+            if (flush_error != null) throw flush_error;
+            while (dirty[0] >= MAX_WRITE_BACK) {
+                try {
+                    dirty.wait();
+                }
+                catch (InterruptedException e) {
+                    throw new InterruptedIOException();
+                }
+            }
+        }
+        new TCFTask<Object>() {
+            public void run() {
+                write_commands.add(fs.write(handle, offset, buf, off, len, new IFileSystem.DoneWrite() {
+                    public void doneWrite(IToken token, FileSystemException error) {
+                        assert write_commands.contains(token);
+                        write_commands.remove(token);
+                        if (error != null) {
+                            for (Iterator<IToken> i = write_commands.iterator(); i.hasNext();) {
+                                if (i.next().cancel()) i.remove();
+                            }
+                        }
+                        synchronized (dirty) {
+                            if (error != null && flush_error == null) flush_error = error;
+                            dirty[0] = write_commands.size();
+                            dirty.notifyAll();
+                        }
+                    }
+                }));
+                synchronized (dirty) {
+                    dirty[0] = write_commands.size();
+                }
+                done(this);
+            }
+        }.getIO();
+        offset += len; 
+    }
+
+    @Override
+    public synchronized void close() throws IOException {
+        if (closed) return;
+        flush();
+        synchronized (dirty) {
+            while (dirty[0] > 0) {
+                try {
+                    dirty.wait();
+                }
+                catch (InterruptedException e) {
+                    throw new InterruptedIOException();
+                }
+            }
+        }
+        new TCFTask<Object>() {
+            public void run() {
+                fs.close(handle, new IFileSystem.DoneClose() {
+                    public void doneClose(IToken token, FileSystemException error) {
+                        if (error != null) error(error);
+                        else done(this);
+                    }
+                });
+            }
+        }.getIO();
+        closed = true;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFTask.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.util;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * A <tt>TCFTask</tt> is an utility class that represents the result of an asynchronous
+ * communication over TCF framework.  Methods are provided to check if the communication is
+ * complete, to wait for its completion, and to retrieve the result of
+ * the communication.
+ * 
+ * TCFTask is useful when communication is requested by a thread other then TCF dispatch thread.
+ * If client has a global state, for example, cached remote data, multithreading should be avoided,
+ * because it is extremely difficult to ensure absence of racing conditions or deadlocks in such environment.
+ * Such clients should consider message driven design, see TCFDataCache and its usage as an example.    
+ * 
+ * If a client is extending TCFTask it should implement run() method to perform actual communications.
+ * The run() method will be execute by TCF dispatch thread, and client code should then call either done() or
+ * error() to indicate that task computations are complete.  
+ */
+public abstract class TCFTask<V> implements Runnable, Future<V> {
+    
+    private V result;
+    private boolean done;
+    private Throwable error;
+    private boolean canceled;
+    private IChannel channel;
+    private IChannel.IChannelListener channel_listener;
+    
+    /**
+     * Construct a TCF task object and schedule it for execution.
+     */
+    public TCFTask() {
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                try {
+                    TCFTask.this.run();
+                }
+                catch (Throwable x) {
+                    if (!done && error == null) error(x);
+                }
+            }
+        });
+    }
+    
+    /**
+     * Construct a TCF task object and schedule it for execution.
+     * The task will be canceled if it is not completed after given timeout.
+     * @param timeout - max time in milliseconds.
+     */
+    public TCFTask(long timeout) {
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                try {
+                    TCFTask.this.run();
+                }
+                catch (Throwable x) {
+                    if (!done && error == null) error(x);
+                }
+            }
+        });
+        Protocol.invokeLater(timeout, new Runnable() {
+            public void run() {
+                cancel(true);
+            }
+        });
+    }
+    
+    /**
+     * Construct a TCF task object and schedule it for execution.
+     * The task will be canceled if the given channel is closed or
+     * terminated while the task is in progress.
+     * @param channel
+     */
+    public TCFTask(final IChannel channel) {
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                try {
+                    if (channel.getState() != IChannel.STATE_OPEN) throw new Exception("Channel is closed");
+                    TCFTask.this.channel = channel;
+                    channel_listener = new IChannel.IChannelListener() {
+
+                        public void congestionLevel(int level) {
+                        }
+
+                        public void onChannelClosed(final Throwable error) {
+                            cancel(true);
+                        }
+
+                        public void onChannelOpened() {
+                        }
+                    };
+                    channel.addChannelListener(channel_listener);
+                    TCFTask.this.run();
+                }
+                catch (Throwable x) {
+                    if (!done && error == null) error(x);
+                }
+            }
+        });
+    }
+    
+    /**
+     * Set a result of this task and notify all threads waiting for the task to complete.
+     * The method is supposed to be called in response to executing of run() method of this task.
+     * 
+     * @param result - the computed result
+     */
+    public synchronized void done(V result) {
+        assert Protocol.isDispatchThread();
+        if (canceled) return;
+        assert !done;
+        assert this.error == null;
+        assert this.result == null;
+        this.result = result;
+        done = true;
+        if (channel != null) channel.removeChannelListener(channel_listener);
+        notifyAll();
+    }
+    
+    /**
+     * Set a error and notify all threads waiting for the task to complete.
+     * The method is supposed to be called in response to executing of run() method of this task.
+     * 
+     * @param error - computation error.
+     */
+    public synchronized void error(Throwable error) {
+        assert Protocol.isDispatchThread();
+        assert error != null;
+        if (canceled) return;
+        assert this.error == null;
+        assert this.result == null;
+        assert !done;
+        this.error = error;
+        if (channel != null) channel.removeChannelListener(channel_listener);
+        notifyAll();
+    }
+
+    /**
+     * Attempts to cancel execution of this task.  This attempt will
+     * fail if the task has already completed, already been canceled,
+     * or could not be canceled for some other reason. If successful,
+     * and this task has not started when <tt>cancel</tt> is called,
+     * this task should never run.  If the task has already started,
+     * then the <tt>mayInterruptIfRunning</tt> parameter determines
+     * whether the thread executing this task should be interrupted in
+     * an attempt to stop the task.
+     *
+     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+     * task should be interrupted; otherwise, in-progress tasks are allowed
+     * to complete
+     * @return <tt>false</tt> if the task could not be canceled,
+     * typically because it has already completed normally;
+     * <tt>true</tt> otherwise
+     */
+    public synchronized boolean cancel(boolean mayInterruptIfRunning) {
+        assert Protocol.isDispatchThread();
+        if (isDone()) return false;
+        canceled = true;
+        error = new CancellationException();
+        if (channel != null) channel.removeChannelListener(channel_listener);
+        notifyAll();
+        return true;
+    }
+
+    /**
+     * Waits if necessary for the computation to complete, and then
+     * retrieves its result.
+     *
+     * @return the computed result
+     * @throws CancellationException if the computation was canceled
+     * @throws ExecutionException if the computation threw an
+     * exception
+     * @throws InterruptedException if the current thread was interrupted
+     * while waiting
+     */
+    public synchronized V get() throws InterruptedException, ExecutionException {
+        assert !Protocol.isDispatchThread();
+        while (!isDone()) wait();
+        if (error != null) {
+            if (error instanceof ExecutionException) throw (ExecutionException)error;
+            if (error instanceof InterruptedException) throw (InterruptedException)error;
+            throw new ExecutionException("TCF task aborted", error);
+        }
+        return result;
+    }
+    
+    /**
+     * Waits if necessary for the computation to complete, and then
+     * retrieves its result.
+     *
+     * @return the computed result
+     * @throws Error if the computation was canceled or threw an exception
+     */
+    public synchronized V getE() {
+        assert !Protocol.isDispatchThread();
+        while (!isDone()) {
+            try {
+                wait();
+            }
+            catch (InterruptedException x) {
+                throw new Error(x);
+            }
+        }
+        if (error != null) {
+            if (error instanceof Error) throw (Error)error;
+            throw new Error("TCF task aborted", error);
+        }
+        return result;
+    }
+
+    /**
+     * Waits if necessary for the computation to complete, and then
+     * retrieves its result.
+     *
+     * @return the computed result
+     * @throws IOException if the computation was canceled or threw an exception
+     */
+    public synchronized V getIO() throws IOException {
+        assert !Protocol.isDispatchThread();
+        while (!isDone()) {
+            try {
+                wait();
+            }
+            catch (InterruptedException x) {
+                throw new InterruptedIOException();
+            }
+        }
+        if (error != null) {
+            if (error instanceof IOException) throw (IOException)error;
+            IOException y = new IOException("TCF task aborted");
+            y.initCause(error);
+            throw y;
+        }
+        return result;
+    }
+
+    /**
+     * Waits if necessary for at most the given time for the computation
+     * to complete, and then retrieves its result, if available.
+     *
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @return the computed result
+     * @throws CancellationException if the computation was canceled
+     * @throws ExecutionException if the computation threw an exception
+     * @throws InterruptedException if the current thread was interrupted
+     * while waiting
+     * @throws TimeoutException if the wait timed out
+     */
+    public synchronized V get(long timeout, TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        assert !Protocol.isDispatchThread();
+        if (!isDone()) {
+            wait(unit.toMillis(timeout));
+            if (!isDone()) throw new TimeoutException();
+        }
+        if (error != null) {
+            if (error instanceof InterruptedException) throw (InterruptedException)error;
+            if (error instanceof ExecutionException) throw (ExecutionException)error;
+            if (error instanceof TimeoutException) throw (TimeoutException)error;
+            throw new ExecutionException("TCF task aborted", error);
+        }
+        return result;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this task was canceled before it completed
+     * normally.
+     *
+     * @return <tt>true</tt> if task was canceled before it completed
+     */
+    public synchronized boolean isCancelled() {
+        return canceled;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this task completed.  
+     *
+     * Completion may be due to normal termination, an exception, or
+     * cancellation -- in all of these cases, this method will return
+     * <tt>true</tt>.
+     * 
+     * @return <tt>true</tt> if this task completed.
+     */
+    public synchronized boolean isDone() {
+        return error != null || done;
+    }
+    
+    /**
+     * Return task execution error if any.
+     * @return Throwable object or null
+     */
+    protected Throwable getError() {
+        return error;
+    }
+    
+    /**
+     * Return task execution result if any.
+     * @return result object
+     */
+    protected V getResult() {
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/.project	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.tm.tcf.docs</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Agent Porting Guide.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,266 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<head>
+    <title>TCF Agent Porting Guide</title>
+</head>
+
+<body lang='EN-US'>
+
+    <h1>TCF Agent Porting Guide</h1>
+
+    <p>
+        Copyright (c) 2009 Wind River Systems, Inc. Made available under the EPL v1.0
+    </p>
+    <p>
+        Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+    </p>
+
+    <h2>Table of Contents</h2>
+    <ul>
+        <li>
+            <a href='#Introduction'>Introduction</a>
+        </li>
+        <li>
+            <a href='#Customizing'>Customizing and Porting TCF Agent</a>
+        </li>
+        <li>
+            <a href='#NewOS'>Porting TCF Agent to a New OS Platform</a>
+        </li>
+        <li>
+            <a href='#NewCPU'>Porting TCF Agent to a New CPU Type</a>
+        </li>
+        <li>
+            <a href='#NewExeFile'>Adding Support For a New Executable File Format</a>
+        </li>
+        <li>
+            <a href='#NewDebugData'>Adding Support For a New Debug Data Format</a>
+        </li>
+        <li>
+            <a href='#NewTransport'>Adding Support For a New Communication Trasport</a>
+        </li>
+    </ul>
+
+    <h2>
+        <a name='Introduction'>Introduction</a>
+    </h2>
+
+    <p>
+        TCF Agent is a lightweight reference implementation of TCF protocol that supports basic debugging and other TCF services.
+        It is written in C and can be used for remote debugging of software written for Linux, Windows XP or VxWorks.
+        See <a href='TCF Getting Started.html'>TCF Getting Started</a> for instructions on how to get the source code and build the agent.
+    </p>
+
+
+    <h2>
+        <a name='Customizing'>Customizing and Porting TCF Agent</a>
+    </h2>
+
+    <p>
+        It is important to know concurrency model used by the agent code before making any changes.
+        Most of the agent code is event driven: it has a main loop that retrieves events from an event queue and executes them sequentially by calling event handlers by a single thread.
+        Single threaded event driven design provides good level of concurrency (equivalent to cooperative multithreading), while greatly reduces need for synchronization -
+        each event dispatch cycle can be viewed as fully synchronized atomic operation.
+    </p>
+    
+    <p>
+        Event driven code should avoid long running or potentially blocking operations in event handlers since they can stop all event processing for indefinite time.
+        Such operations should use asynchronous APIs (like POSIX Asynchronous I/O), or should be performed by background threads.
+        Treat background threads with extreme caution - agent data structures are not intended for multithreaded access.
+        Background thread scope should be limited to a single module and it should not call agent public APIs.
+        Instead they should communicate with the rest of the code by posting events.
+    </p>
+    
+    <p>
+        An event is essentially a function pointer (a call-back) that points to event handler, plus a data pointer.
+        Call-backs are also used throughout the agent code to subscribe listeners for various state change notifications.
+        Using events and call-backs, as a design principle, is also known as inversion of control.
+        Note that, in general, inversion of control is not compatible with traditional multithreaded programming model that used mutexes to protect shared data from racing conditions.
+    </p>
+
+    <p>
+        Most of TCF agent configuration is done at compile time.
+        Conditional compilation statements in the source code assume that both the agent and inferior code will run on same OS platform and
+        on same CPU type that were used to build the agent.
+        Building an agent that can run on one machine while controlling execution of code on another machine might be possible, but not fully supported at this time.
+    </p>
+
+    <p>
+        Header file <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a> contains macro definitions that control agent configuration.
+        All C files in the agent code include <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a> before other header files.
+        Individual services or features can be enabled or disabled by changing definitions in the file.
+        Also, macro values can be overwritten by using -D option in C compiler command line.
+        Agent <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/Makefile'>Makefile</a> contains additional logic that makes it even more convenient to build different agent configurations.
+    </p>
+    
+    <p>
+        It should be much easier to port the agent if you don't need all TCF services.
+        For example, for RSE integration you only need File System, System Monitor and Processes services,
+        so you can disable all other services by editing <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a>.
+    </p>
+
+    <p>
+        It is better to create a separate directory with alternative versions of
+        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a>,
+        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.h'>context.h,</a>
+        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.c'>context.c,</a>
+        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/Makefile'>Makefile,</a>
+        etc., instead of editing original files.
+        The idea is that Makefile will search that directory first, and if a file not found there, it will search original agent sources.
+        See <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/examples/org.eclipse.tm.tcf.examples.daytime.agent'>examples/org.eclipse.tm.tcf.examples.daytime.agent</a>
+        for an example of a custom TCF agent.
+        Of course, if changes are generic enough to be useful for other ports, then it is better to change code in the main directory.
+    </p>
+
+    <p>
+        Please, consider contributing your changes of the source code back to eclipse.org.
+    </p>
+
+    <h2>
+        <a name='NewOS'>Porting TCF Agent to a New OS Platform</a>
+    </h2>
+
+    <p>
+        In order to improve portability, instead of using non-portable native OS calls, agent code uses POSIX APIs whenever possible.
+        When a POSIX API is not available for particular platform, and it can be easily emulated, it is done in mdep.h/mdep.c files.
+        For example, mdep.h/mdep.c contains emulation of POSIX Threads for Win32, since the API is not available with Microsoft C compiler.
+        API emulation does not have to be complete, it only needs to implement functionality that is used by the agent.
+    </p>
+
+    <p>
+        When it is not possible or not feasible to use portable POSIX APIs, the agent code contains conditional compilation statements that
+        use well known macros like WIN32, __CYGWIN__, __MINGW32__, etc. Such places might require editing when porting to a new OS.
+    </p>
+    
+    <h2>
+        <a name='NewCPU'>Porting TCF Agent to a New CPU Type</a>
+    </h2>
+
+    <p>
+                Searching TCF agent source code for __i386__ is a good way to find all places where the source code depends on CPU type.
+        </p>
+    
+        <p>
+                There are several files in the code that might need changes in order to support a new CPU type:
+        </p>
+
+    <dl>
+        <dt>
+            <b>
+                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.c'>context.c</a>
+            </b>
+        </dt>
+        <dd>
+            The module provides low level debugger functionality: attach/detach, suspend/resume, single step, memory read/write.
+            It uses OS debug APIs to do its job. Most of the code does not depend on CPU type, however, single stepping is not always directly
+            supported by OS, and its implementation needs to be reviewed and changed to support new CPU type.
+        </dd>
+        <dt>
+            <b>
+                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/dwarfexpr.c'>dwarfexpr.c</a>
+            </b>
+        </dt>
+        <dd>
+            The module implements evaluation of <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> expressions.
+            The module is used only if the agent is built to support
+            <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF</a> executable file format and
+            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> debugging data format.
+            No need to change the module if <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF</a> or
+            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> support is not required.
+            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> expressions can have references to CPU registers.
+            Register access code needs to be changed to support new CPU type.
+            Note that different compilers can use different numbers to identify same registers of same CPU.
+        </dd>
+        <dt>
+            <b>
+                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/registers.c'>registers.c</a>
+            </b>
+        </dt>
+        <dd>
+            The module implements <a href='TCF Service - Registers.html'>Registers service</a>. The code has static variable "regs_index" that contains a table of CPU registers.
+            The table holds names, offsets and sizes of CPU registers. Offset and size define location of register data in REG_SET structure,
+            which represents snapshot of register values of an execution context. Definition of the variable needs to be changed to support new CPU type.
+        </dd>
+        <dt>
+            <b>
+                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/stacktrace.c'>stacktrace.c</a>
+            </b>
+        </dt>
+        <dd>
+            The module implements <a href='TCF Service - Stack Trace.html'>Stack Trace service</a>.
+            The module contains "trace_stack" function that creates stack trace by walking a stack of an executable context.
+            Stack trace data format is defined by two struct declarations: StackTrace and StackFrame.
+            The data structure is generic, however the code that created the data structure is CPU dependand.
+            Alternative version of "trace_stack" function needs to be provided to support new CPU type.
+        </dd>
+    </dl>
+
+    <h2>
+        <a name='NewExeFile'>Adding Support For a New Executable File Format</a>
+    </h2>
+
+    <p>
+        For source level debugging TCF agent needs to understand executable file format.
+        Source level debugging is supported by providing two services: Symbols and Line Numbers.
+        The services are optional, and if they are disabled no support for executable file format is needed.
+        At this time the agent supports <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF (Executable and Linking Format)</a>
+        and <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE (Portable Executable)</a> files.
+        ELF is very popular format in Unix-like and embedded systems, and PE is used in Windows operating systems.
+    </p>
+
+    <p>
+        ELF supported in the agent is developed from scratch, has no external dependences, and is available in source form as part of the agent source code.
+        The code might require changes to support a particular flavor of ELF.
+        Probably the most tricky part of the code is interface to the system loader.
+        The agent needs to know when an ELF file is loaded into or removed from target memory so it can update symbol tables and breakpoints.
+        For that it plants an internal (not visible to clients) breakpoint (aka eventpoint) inside system loader code.
+        The breakpoint allows agent to intercept control every time an ELF file is loaded or unloaded.
+    </p>
+
+    <p>
+        PE support in the agent is implemented by using DBGHELP.DLL. This DLL is included in Windows operating system.
+        However, older versions of the DLL might not provide all necessary functionality.
+        To obtain the latest version of DBGHELP.DLL, go to <a href='http://www.microsoft.com/whdc/devtools/debugging/default.mspx'>
+        http://www.microsoft.com/whdc/devtools/debugging/default.mspx</a> and download Debugging Tools for Windows.
+    </p>
+
+    <p>
+        Support for a completely new file format would require to develop alternative versions of symbols_xxx.c and linenumbers_xxx.c files.
+        See <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/symbols_elf.c'>symbols_elf.c</a>
+        and <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/linenumbers_elf.c'>linenumbers_elf.c</a>
+        as example implementation of the services.
+    </p>
+
+    <h2>
+        <a name='NewDebugData'>Adding Support For a New Debug Data Format</a>
+    </h2>
+
+    <p>
+        For source level debugging TCF agent needs to understand debug data format.
+                Debug data is usually reside in a section of an executable file, so the file format should be supported, see <a href='#NewExeFile'>Adding Support For a New Executable File Format</a>.
+                At this time the agent supports <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> and
+                <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE (Portable Executable)</a> debug data formats.
+                <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> support is implemented as part of the agent source code,
+                and <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE</a> data is accessed using DBGHELP.DLL, which is included in Windows operating system.
+    </p>
+
+    <h2>
+        <a name='NewTransport'>Adding Support For a New Communication Transport</a>
+    </h2>
+
+    <p>
+        Current agent code uses TCP/IP as the transport protocol to open communication channels.
+        The agent code can be easily modified to support other transport protocols, like UDP, USB, etc.
+    </p>
+
+        <p>
+            Files <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel_tcp.h'>channel_tcp.h</a>
+        and <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel_tcp.c'>channel_tcp.c</a> provide support for TCP/IP transport.
+        To support another protocol one would need to develop similar code using TCP support as an example.
+        </p>
+
+        <p>
+        Adding new transport would also require to modify functions channel_server() and channel_connect() in
+        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel.c'>channel.c</a>.
+        </p>
+</body>
+</HTML>
Binary file dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Architecture.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Context Identifier Explanation.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,257 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+        <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1251">
+        <TITLE>TCF Context Identifier Explanation</TITLE>
+        <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.2  (Win32)">
+        <META NAME="CREATED" CONTENT="20070830;12134342">
+        <META NAME="CHANGEDBY" CONTENT="Eugene Tarassov">
+        <META NAME="CHANGED" CONTENT="20070830;12351368">
+        <STYLE TYPE="text/css">
+        <!--
+                H1 { color: #000000 }
+                P { color: #000000 }
+                P.western { font-size: 13pt }
+                H2 { color: #000000 }
+        -->
+        </STYLE>
+</HEAD>
+<BODY LANG="en-US" TEXT="#000000" DIR="LTR">
+<P CLASS="western" STYLE="border-top: none; border-bottom: 1.00pt solid #4f81bd; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.06in; padding-left: 0in; padding-right: 0in">
+<FONT COLOR="#17365d"><FONT FACE="Cambria"><FONT SIZE=6 STYLE="font-size: 26pt">TCF
+Context Identifier Explanation</FONT></FONT></FONT></P>
+<P CLASS="western"><FONT COLOR="#4f81bd"><FONT FACE="Cambria"><FONT SIZE=3><I>Felix
+Burton, Wind River, Version 2</I></FONT></FONT></FONT></P>
+<H1><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Introduction</B></FONT></FONT></FONT></H1>
+<P CLASS="western">Most if not all TCF services functions need some
+way to identify what entity e.g. process, thread, task, semaphore,
+breakpoint, flash device, device on JTAG scan chain, etc they should
+operate on. To do this TCF uses a context identifier (aka ContextId).
+This document is attempting to explain how ContextIds are intended to
+be used. This is document does not define actual services or exact
+context hierarchies, but for the purpose of making things more
+concrete examples may be used.</P>
+<H2 LANG="en-GB" STYLE="margin-top: 0in; margin-bottom: 0.04in"><FONT COLOR="#4f81bd"><FONT FACE="Cambria"><FONT SIZE=3 STYLE="font-size: 13pt"><B>Why
+a single ContextId?</B></FONT></FONT></FONT></H2>
+<P CLASS="western">A prudent question to ask is why use a single
+ContextId instead of having separate IDs for each notion e.g. a
+ProcessId, ThreadId, BreakpointId, JTAGDeviceId, etc. Having separate
+IDs is used in many existing debug APIs and protocols and may seem
+intuitive. However, there are several issues with this approach:</P>
+<P CLASS="western">1. It is inflexible in that it requires each
+function to upfront know how many levels are needed and what type of
+context each level represent.</P>
+<P CLASS="western">2. This in turn makes it difficult to use the same
+API for different environments since they often have different types
+of IDs and has different number of levels. For example Linux have
+processes and threads while OCD have cores.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Context
+identifier</B></FONT></FONT></FONT></H1>
+<P CLASS="western">ContextIds are opaque handles that only have
+meaning to the service that created them or its peer services. They
+are created for clients, by service implementations to identify some
+entity handled by the services. Clients can use contextIds in the
+following ways:</P>
+<P CLASS="western">1. Pass to the originating service or peer
+services</P>
+<P CLASS="western">2. Compare for equality with other contextIds
+retrieved from the originating service or peer services.</P>
+<P CLASS="western">More specifically, clients should not try to
+decode or extract information from the contextId, instead they should
+make requests to the originating service or peer services using the
+contextId for information or action.</P>
+<P CLASS="western">As can be seen from the above, contextIds created
+by one service can be used by its peer services. The service should
+either to do something useful or to give an error indicating that the
+contextId is not relevant to that particular service. To guarantee
+that a contextId created by service A and passed to service B is not
+misinterpreted to be something other that what service A intended,
+there must be a global naming scheme for contextId within a target.</P>
+<P CLASS="western">This allows two or more services to create the
+same contextId when they operate on the same entity. It means that a
+single contextId can have multiple aspects that are handled by
+different services, thereby allowing decoupling of service
+interfaces.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Context
+hierarchies</B></FONT></FONT></FONT></H1>
+<P CLASS="western">Entities represented by contextIds typically
+relate to similar entities in a list or parent/child relationship.
+Examples, 1) Linux processes have children threads, 2) a suspended
+thread has a list of stack frames, and 3) threads have register
+groups which have registers which can have fields. These
+relationships form context hierarchies.</P>
+<P CLASS="western">Depending on the system there may be several
+different context hierarchies. For example contexts available for
+JTAG debugging include:</P>
+<P CLASS="western">1. debugging</P>
+<P CLASS="western">2. memory access</P>
+<P CLASS="western">3. register access</P>
+<P CLASS="western">4. JTAG access</P>
+<P CLASS="western">Interestingly there may also be relations between
+the different hierarchies. For example contexts available for
+debugging may correspond with contexts available for memory access. A
+typical example of this is Linux where a contextId representing a
+process can be used for debugging as well as memory access, open file
+table access, memory map access, etc. In such cases, the same
+contextId should be used in all hierarchies. This allows clients to
+detect when hierarchies come together or split apart so the client
+can represent the relationships properly to the user for example in a
+GUI.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Accessing
+context information</B></FONT></FONT></FONT></H1>
+<P CLASS="western">Information associated with a contextId can be
+sufficiently large to make it impractical to transfer all associated
+information to the client in a single request. To reduce the amount
+of information transferred while still allowing the implementation to
+be relatively simple; the information is categorized as follows:</P>
+<P CLASS="western">1. Child context references per service</P>
+<P CLASS="western">2. Slow changing properties per service, a.k.a.
+properties</P>
+<P CLASS="western">3. Fast changing properties per service, a.k.a.
+state or status 
+</P>
+<P CLASS="western">Category 1 provides a simple way to express
+unbounded lists of related contextIds. If such a list becomes too
+large the service can split the list into a list of lists, list of
+lists or lists, etc as needed.</P>
+<P CLASS="western">Category 2 and 3 provides a simple way to express
+arbitrary information about the context in the form of a key/value
+pair. Properties may also contain contextId references for example
+for the parent context.</P>
+<P CLASS="western">The split between category 2 and 3 allows the
+service to handle fast changing information in a more optimal way and
+allows it to handle slow changing information in a more simple way.
+It is up to the service to define what information is slow vs. fast
+changing.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>ContextId
+formatting</B></FONT></FONT></FONT></H1>
+<P CLASS="western">The ContextId is represented as string between
+clients and services. The formatting of the string with one exception
+is completely up to the implementation that created the contextId.
+The exception is the ContextId prefix explained below. The remainder
+of the string can be formatted in any way that the service descries.
+Two typical ways comes to mind:</P>
+<P CLASS="western">1. Hierarchical list where each level is spelled
+out. For example on Linux:</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">a. A process could be
+identified by &ldquo;ppid&rdquo; and a thread by &ldquo;ppid,ttid&rdquo;</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">b. A register set by
+&ldquo;ppid,ttid,rset&rdquo;</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">c. A stack frame by
+&ldquo;ppid,ttid,slevel&rdquo;</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">d. A local variable on
+a specific stack level by &ldquo;ppid,ttid,slevel,vname&rdquo;</P>
+<P CLASS="western">2. Flat ID that the generating service used to do
+table lookup for more information. For example</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">a. Index into an array
+&ldquo;tableIndex,generationNumber&rdquo;</P>
+<P CLASS="western" STYLE="margin-left: 0.79in">b. Key used for hash
+lookup &ldquo;sequentialNumber&rdquo;</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>ContextId
+prefix</B></FONT></FONT></FONT></H1>
+<P CLASS="western">When information from more than one channel is
+joined together to when value-adding services between the two
+endpoints create contextIds it must be possible to for every service
+to determine if a contextId was created by it or a foreign entity. To
+do this, each service manager is assigned a unique contextId prefix
+that all its generated contextIds should be prefixed with followed by
+the colon (:) character. For example imagine that GDB was designed to
+be a value-adding service, contextIds created on this level could be
+prefixed by &ldquo;gdb:&rdquo; to guarantee that the target would be
+able to return error if such contextId was given to it instead of to
+the services in GDB.</P>
+<P CLASS="western">The prefix used by a service manager is
+dynamically assigned by the client initiating the connection. A
+limited TCF endpoint implementation is not required to support
+contextId prefixing. However, in such case it is only be possible to
+have value-adding services if they intercept all services on the
+endpoint.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Context
+information caching</B></FONT></FONT></FONT></H1>
+<P CLASS="western">Clients will most likely need to cache context
+information in order to keep the amount of information transferred to
+a minimum. Such caching should be based on the contextId, service
+name, and type of data i.e. children contextIds, properties or state.</P>
+<P CLASS="western">The suggested implementation is to use a two stage
+cache lookup, where the first stage is using only the contextId and
+the second stage using the service name and the type of data. The
+reason for the two stage approach is to allow easy flushing of the
+cached information when contextIds are removed.</P>
+<P CLASS="western">Services support caching in clients by sending
+events for any changes to the information. The following events are
+expected to be generated by services when needed:</P>
+<P CLASS="western">1. Children added. The event includes the parent
+contextId, service name and list of contextIds and their properties
+to be added to the cache. Clients that have not populated the cache
+for the specified parent contextId should ignore this event.</P>
+<P CLASS="western">2. Children removed. The event includes the parent
+contextId, service name and list of contextIds to be removed from the
+list. When received, clients should update cache by removing all
+listed contextIds for the specified parent contextId and service
+name.</P>
+<P CLASS="western">3. Children changed. The event includes the parent
+contextId and service name. This event does not include the updated
+list of contextIds; instead clients are expected to reread the list
+of children if they need it. When received, clients should invalidate
+the list of children contextIds for the specified parent contextId
+and service name.</P>
+<P CLASS="western">4. Properties changed. This event includes a list
+of contextId, service name and properties. When received, clients
+should update cache with the new properties.</P>
+<P CLASS="western">5. State or status changed. This event includes
+contextId, service name and state or status. When received, clients
+should update cache with the new state or status.</P>
+<P CLASS="western">Invalidating or removing entries from the list of
+children contextIds should also result in recursively invalidating
+all cache entries for the removed contextIds. This is necessary to
+avoid stale cache entries to linger when a removed contextId is
+reused for a new context.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Relationship
+between services</B></FONT></FONT></FONT></H1>
+<P CLASS="western">Even though service interfaces should not have any
+direct dependencies, they can have context hierarchy relationships.</P>
+<P CLASS="western">A good example of such relationship is between the
+&ldquo;run control&rdquo; service and the &ldquo;memory&rdquo;
+service. It seems to make sense to specify that the run control
+hierarchy is &ldquo;rooted&rdquo; in the memory hierarchy since it is
+hard to imagine executing instructions without a memory that stores
+the instructions.</P>
+<P CLASS="western">Another example is for run control, register and
+stack trace services where it seems logical to define registers and
+stack frame hierarchies to be &ldquo;rooted&rdquo; in the run control
+hierarchy.</P>
+<P CLASS="western">By &ldquo;rooted&rdquo; we mean that roots for one
+hierarchy can be found in another hierarchy.</P>
+<P CLASS="western">Usually clients need only one particular hierarchy
+at the time, however some clients, for example in Eclipse the Debug
+View is designed to be provide selection for run control, memory
+view, locals view, registers view, etc in one place, so it needs to
+merge memory, run control and stack trace hierarchies in order to
+provide single tree for selection.</P>
+<P CLASS="western">The services interface specification should define
+the rooting of its context hierarchy, if any. As mentioned in the
+example above, run control service is rooted in the memory hierarchy,
+and register and stack trace services are rooted in the run control
+hierarchy.</P>
+<P CLASS="western">It may be possible to a service context hierarchy
+to be rooted in multiple hierarchies.</P>
+<P CLASS="western">Which context hierarchies are merged is up to the
+implementer of the client.</P>
+<H1 LANG="en-GB"><FONT COLOR="#365f91"><FONT FACE="Cambria"><FONT SIZE=4><B>Context
+hierarchy roots</B></FONT></FONT></FONT></H1>
+<P CLASS="western">For some services it is possible to use &ldquo;null&rdquo;
+as a special parent contextId to the &ldquo;get children&rdquo;
+command to retrieve a list of root contextIds. The service interface
+definition should specify if retrieval of roots is supported by the
+service.</P>
+<P CLASS="western">Example services that would support the &ldquo;null&rdquo;
+parent contextId are JTAG access and kernel awareness services since
+this is global information in the target.</P>
+<P CLASS="western">Example services that would not support the &ldquo;null&rdquo;
+parent contextId are register and stack trace services since parent
+contextId for registers and stack frames is usual obtained through
+run control service.</P>
+<P CLASS="western"><BR><BR>
+</P>
+</BODY>
+</HTML>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Getting Started.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,237 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework: Getting Started</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework: Getting Started</h1>
+ 
+<p>Copyright (c) 2007, 2008 Wind River Systems, Inc. Made available under the EPL v1.0
+<p>Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+
+<h2>Table of Contents</h2>
+<ul>
+    <li><a href='#Workspace'>Creating Eclipse Workspace</a>
+    <li><a href='#Plugins'>TCF Plugins</a>
+    <li><a href='#Agent'>Building TCF Agent</a>
+    <li><a href='#Browsing'>Browsing Agent Source Code in CDT</a>
+    <li><a href='#RSE'>Using TCF With Remote System Explorer</a>
+    <li><a href='#Debugger'>Using TCF With Eclipse Debugger</a>
+</ul>
+
+<h2><a name='Workspace'>Creating Eclipse Workspace</a></h2>
+
+<p>Eclipse can be used for developing clients for TCF in Java. 
+TCF host side code is organized into several Eclipse plug-in projects,
+below are steps to create and populate Eclipse workspace with TCF projects:</p>
+
+<ul>
+   <li>Install JDK 1.5.0 or later, recommended 1.6.0
+   <li>Install <b>Eclipse Classic SDK 3.4</b>, last tested with 3.4.2, recommended 3.4.2<br>
+       <a href='http://download.eclipse.org/eclipse/downloads/'>http://download.eclipse.org/eclipse/downloads/</a>
+   <li>Install <b>TM RSE SDK 3.0</b> or later, last tested with 3.0.3, recommended 3.0.3<br>
+       <a href='http://download.eclipse.org/dsdp/tm/downloads/'>http://download.eclipse.org/dsdp/tm/downloads/</a>
+   <li><b>Optional</b> dependencies for TCF/DSF/CDT integration: these are not required by
+       TCF itself, and not needed for RSE integration or for TCF based debugger demo,
+       use these for future development:
+       <ul>
+       <li>CDT (Eclipse C/C++ Development Tools SDK) 5.0 or later, last tested with 5.0.2, recommended 5.0.2<br>
+       <a href='http://www.eclipse.org/cdt/downloads.php'>http://www.eclipse.org/cdt/downloads.php</a>
+       <li>DD (Device Debug) SDK 1.0.0<br>
+       <a href='http://download.eclipse.org/dsdp/dd/downloads/'>http://download.eclipse.org/dsdp/dd/downloads/</a>
+       </ul>
+   <li>Checkout TCF code from <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk'>Eclipse SVN repository</a>:
+       <pre>svn co svn://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk</pre>
+   <li>Run Eclipse:
+      <pre>eclipse.exe -vm &lt;JDK path&gt;\bin\javaw.exe -data &lt;Workspace path&gt; -vmargs -Xmx200M</pre>
+   <li>Open "Java" perspective.
+   <li>In "Package Explorer" view: do right click and then select "Import...".
+   <li>Select "General/Existing Projects into Workspace" and click "Next".
+   <li>Select root directory: &lt;TCF Root&gt;\plugins, and click "Next".
+       <ul>
+       <li>If DD-DSF and/or CDT are not installed, don't import the following two plugins
+       into your workspace:
+               <ul>
+           <li>org.eclipse.tm.tcf.dsf
+           <li>org.eclipse.tm.tcf.dsf.ui
+           <li>org.eclipse.tm.tcf.cdt.ui
+           </ul>
+       </ul>
+   <!--
+   <li><b>Optional</b> for browsing dependencies:<ul>
+       <li>In Package Explorer: do right click and select "Import...".
+       <li>Select "Plug-in Development/Plug-ins and Fragments" and click "Next".
+       <li>Select "Import plug-ins and fragments required by existig workspace plug-ins" and click "Next".
+       <li>Click "Select All", then click "Finish".
+   </ul></li>
+   -->
+</ul>
+
+<!--
+<p>Alternative way to get CDT, DSF and RSE installed:
+<ul>
+   <li>Get Eclipse for C/C++ Package from <a href='http://www.eclipse.org/downloads/'>
+       http://www.eclipse.org/downloads/</a> - it includes CDT.
+   <li>Do "Help > Software Updates > Find and Install > Search for New Features to Install > Next"
+   <li>Select "Europa Discovery Site", press "Finish"
+   <li>Select following:
+     <ul>
+       <li>Remote Access and Device Development
+       <ul>
+          <li>Remote System Explorer End-User Runtime
+          <li>Debugger Services Framework end-user and extender SDK
+       </ul>
+     </ul>
+   <li>Press "Select Required" if in Error
+   <li>Press "Next", "Accept", "Next", "Finish"
+</ul>
+-->
+
+<h2><a name='Plugins'>TCF Plugins</a></h2>
+
+<p>TCF plugins source code is stored in <code>&lt;TCF Root&gt;\plugins</code> directory.
+
+<dl>
+    <dt><b>org.eclipse.tm.tcf</b>
+    <dd>This is the main TCF plugin. It contains Eclipse integration code for the framework.
+    It is the only TCF plugin, which (together with its fragments) should be required by a TCF client. The rest of TCF plugins are
+    clients developed as a reference implementation or for demonstration purposes. 
+    <p>
+    <dt><b>org.eclipse.tm.tcf.core</b>
+        <dd>This is a fragment of <b>org.eclipse.tm.tcf</b> plugin. It contains the framework itself and interfaces for standard services.
+        The Java code in the fragment does not have any Eclipse dependencies and can be used outside Eclipse.
+        <p>
+    <dt><b>org.eclipse.tm.tcf.debug, org.eclipse.tm.tcf.debug.ui</b>
+    <dd>This is a prototype code that connects Eclipse Debug Framework and Target Communication Framework.
+    It allows to launch Eclipse debug session by connecting to a target running TCF agent,
+    and then perform basic debugging tasks, like resuming, suspending, single-stepping, setting/removing breakpoints, etc.
+    The code can be used as a reference for developing new TCF clients.
+    <p>
+    <dt><b>org.eclipse.tm.tcf.dsf, org.eclipse.tm.tcf.dsf.ui</b>
+    <dd>This code allows Debugger Services Framework (DSF) clients to access targets using TCF as comminucation protocol.
+    It includes implementation of DSF services as TCF clients.
+    <p>
+    <dt><b>org.eclipse.tm.tcf.rse</b>
+    <dd>This plugin allows Remote System Explorer (RSE) to connect to remote machines using TCF as communication protocol.
+    It includes implementation of RSE services as TCF clients.
+    <p>
+    <dt><b>org.eclipse.tm.tcf.cdt.ui</b>
+    <dd>This optional plugin improves integration between CDT and TCF debugger prototype.
+        It helps to search for CDT projects and executable files when creating TCF launch configuration.
+    <p>
+    <dt><b>org.eclipse.tm.tcf.examples.daytime</b>
+    <dd>This is an example plugin.
+    The Example shows how TCF/Java binding can be extended for a new, user defined service.
+    The plugin provides Java binding for DayTime service.
+    Also, see directory <code>&lt;TCF Root&gt;/examples/org.eclipse.tm.tcf.examples.daytime.agent</code>
+    for example code of a customized TCF agent, which implements DayTime service.
+</dl>
+
+<h2><a name='Agent'>Building TCF Agent</a></h2>
+
+<p><b>CDT</b> can be used to build TCF agent.
+CDT .project file is located in <code>&lt;TCF Root&gt;/agent</code> directory.
+
+<p><b>Linux</b>: To build the agent:
+<ul>
+   <li>Run <code>make</code> command in <code>&lt;TCF Root&gt;/agent</code> directory.
+   <li>Start agent: <pre>GNU/Linux/i686/Debug/agent -L- -l0</pre>
+       Use other -l option values to increase agent log details level.
+</ul>
+
+<p><b>Windows</b>: For building the agent, there are two possibilities:<ul>
+<li>Building with gcc (freely available from <a href="http://wascana.sourceforge.net/">Wascana</a>,
+<a href="http://www.cygwin.com">Cygwin</a> or the
+<a href="http://www.mingw.org/">MinGW32 project</a>): run
+<pre>make</pre> or <pre>make SYSOP=Msys</pre>
+in the agent directory.</li>
+
+<li>Building with Microsoft Visual C++:
+open workspace file <code>&lt;TCF Root&gt;/agent/agent.sln</code>
+and then build and run the agent using Development Studio commands. If getting an error about
+<tt>IPHlpApi.h</tt> missing, you'll need to install the latest
+<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=0BAF2B35-C656-4969-ACE8-E4C0C0716ADB&displaylang=en">MS Platform SDK</a>.
+For the free <a href="http://www.microsoft.com/express/vc/">Visual C++ Express Edition</a>, the
+following changes in settings may be necessary:<ul>
+  <li>Project &gt; Properties &gt; C/C++ &gt; Preprocessor &gt; Preprocessor Definitions:
+       add <tt>_CRT_SECURE_NO_DEPRECATE</tt></li>
+  <li>Project &gt; Properties &gt; Linker &gt; Input &gt; Additional Dependencies :
+       add <tt>shell32.lib</tt></li>
+</ul></li> 
+</ul></p>
+
+<p>On <b>VxWorks</b>, line number mapping and the SysMonitor service (needed for RSE Processes
+Demo) are not yet implemented.<br/>
+To build the agent: Use Wind River Workbench 3.0 or 3.1, and VxWorks 6.6 or 6.7 to create a Kernel Module
+project out of source code in <code>&lt;TCF Root&gt;/agent</code> directory. Use Workbench
+commands to build and run the agent. To run the agent on VxWorks Simulator
+you will need to setup a simulated network - see Networking with the VxWorks Simulator chapter
+in Wind River VxWorks Simulator user's guide for details.</p>
+
+<h2><a name='Browsing'>Browsing Agent Source Code in CDT</a></h2>
+On Linux, the default configuration from the CDT .project file included in TCF
+should be fine for correctly browsing the agent source code. Linux is recommended
+for working on the agent anyways, because most features are implemented already.
+<p>
+On Windows, open Project Properties of the agent project, and under C/C++ General &gt;
+Indexer switch the configuration to "Win32 - Cygwin" or "Win32 - DevStudio"
+as needed.
+<p>
+For VxWorks, browsing should be configured automatically through the WR Workbench
+Kernel Module Project.
+
+<h2><a name='RSE'>Using TCF With Remote System Explorer</a></h2>
+
+<p>Remote System Explorer is an Eclipse based component that allows users to create connections to remote machines and
+explore their file systems, see list of processes and access some other resources, like remote shells.
+Remote System Explorer has been designed as a flexible, extensible framework to which Eclipse plug-in developers can
+contribute their own system definitions, actions, etc.</p>
+
+<p>Plugin <b>org.eclipse.tm.tcf.rse</b> enables use of Processes and Files subsystems of Remote System Explorer over TCF.
+It also extends Processes subsystem to include CPU utilization data and some other process attributes in RSE views.</p>
+
+<p>To connect a remote machine over TCF:</p>
+<ul>
+   <li>Make sure TCF agent is running on remote machine.
+   <li>Run Eclipse with RSE and TCF plugins installed.
+   <li>In Eclipse, do "Window/Open Perspective/Remote System Explorer" command.
+   <li>In "Remote Systems" view: do right click and select "New/Connection..."
+   <li>In "New Connection" dialog box: select TCF and press "Next" button.
+   <li>Enter "Host name" - IP host name ot the target machine, and "Connection name" - arbitrary string to name new connection.
+   Press "Finish" button.
+   <li>New connection should appear in "Remote Systems" view and it is ready to be explored.
+</ul>
+
+<p>RSE features supported by TCF connection:
+<ul>
+    <li>File Subsystem: full support, i.e. browse, upload, download, copy, move, delete
+    <li>Processes: browse, including parent/child relationship
+</ul>
+
+<h2><a name='Debugger'>Using TCF With Eclipse Debugger</a></h2>
+
+<p>Plugins <b>org.eclipse.tm.tcf.debug</b> and <b>org.eclipse.tm.tcf.debug.ui</b> allow to start a debug session
+by connecting to a machine runnning TCF agent.
+
+<p>To start a debug session over TCF:</p>
+<ul>
+   <li>Make sure TCF agent is running on remote machine.
+   <li>Run Eclipse with TCF plugins installed.
+   <li>In Eclipse, do "Window/Open Perspective/Debug" command.
+   <li>Do "Run/Open Debug Dialog..." command.
+   <li>In "Debug" dialog box: select "Target Comminucation Framework" configuration type and press "New" button.
+   <li>Enter a name for the configuration.
+   <li>Select a target machine in "Available targtes" list. The list shows targets autodetected on local network.
+   <li>Press "Run Diagnostics" button to test connectivity for selected target.
+   <li>Enter a program name to run in debug session, for example "/bin/ls".
+   <li>Press "Debug" to start the debugger.
+</ul>
+
+<p>In TCF debug session "Debug", "Breakpoints", "Registers", "Variables" and "Expressions" views are populated.
+Source level debugging is fully supported if the source code can be found in a CDT project in current workspace.
+</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Linux Agent Prototype.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,275 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+
+<head>
+        <TITLE>TCF Agent Prototype Implementation</TITLE>
+</head>
+
+<body LANG="EN-US">
+
+<h1>TCF Agent Prototype Implementation</h1>
+
+<p>
+    Copyright (c) 2009 Wind River Systems, Inc. Made available under the EPL v1.0
+</p>
+<p>
+    Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+</p>
+
+<h2>Table of Contents</h2>
+<ul>
+    <li>
+        <a href='#Introduction'>Introduction</a>
+    </li>
+    <li>
+        <a href='#Framework'>Target Communication Framework</a>
+    </li>
+    <li>
+        <a href='#Services'>Services</a>
+    </li>
+    <li>
+        <a href='#Context'>Executable Context Handling</a>
+    </li>
+    <li>
+        <a href='#EventQueue'>Agent Event Queue</a>
+    </li>
+    <li>
+        <a href='#Misc'>Misc</a>
+    </li>
+    <li>
+        <a href='#Architecture'>Architecture</a>
+    </li>
+</ul>
+
+<h1><a name='Introduction'>Inroduction<a></h1>
+
+<p>This is a brief description of the TCF
+agent prototype implementation.</p>
+
+<p>The agent is implemented in C.
+The code mostly uses POSIX APIs to improve portability.
+
+
+<p>The agent is implemented as
+an event driven program. The main event queue is handled by a single
+thread &ndash; the event dispatch thread. Some sub-systems are using
+other threads locally, but will never call other sub-systems using
+these threads. Instead an event will be placed on the main event
+queue to handle the inter sub-system communication.</p>
+
+<p>Main program parses command line options and initialized sub-systems</p>
+<p>Files:</p>
+<ul>
+        <li>main.c</li>
+</ul>
+
+<h1><a name='Framework'>Target Communication Framework</a></h1>
+
+<h3>Command and Event Registration and Dispatch</h3>
+
+<p>This module handles registration of command and
+event handlers. It is called when new messages are received and will
+dispatch messages to the appropriate handler. It has no knowledge of
+what transport protocol is used and what services do.</p>
+<p>Files:</p>
+<ul>
+        <li>protocol.c</li>
+        <li>protocol.h</li>
+</ul>
+
+<h3>Transport Layer</h3>
+
+<p>Implements input and output stream over TCP/IP
+transport and UDP based auto discovery.</p>
+<p>Files:</p>
+<ul>
+        <li>channel.c</li>
+        <li>channel.h</li>
+        <li>channel_tcp.c</li>
+        <li>channel_tcp.h</li>
+        <li>discovery.c</li>
+        <li>discovery.h</li>
+        <li>discovery_udp.c</li>
+        <li>discovery_udp.h</li>
+        <li>tcf.h</li>
+</ul>
+
+<h3>Input and Output Stream Interface and Library</h3>
+
+<p>This module defines generic input and output stream
+interfaces and supporting library functions.</p>
+<p>Files:</p>
+<ul>
+        <li>streams.c</li>
+        <li>streams.h</li>
+</ul>
+
+<h1><a name='Services'>Services</a></h1>
+
+<h3>Breakpoint</h3>
+
+<p>The breakpoint services implements a global
+breakpoint list.</p>
+<p>Files:</p>
+<ul>
+        <li>breakpoints.c</li>
+        <li>breakpoints.h</li>
+</ul>
+
+<h3>Run Control</h3>
+
+<p>This module implements the run control service. It
+builds uses the context module to do low level control of contexts.
+It implements a &ldquo;safe queue&rdquo; which contains events that
+that should be processed then executable contexts are suspended. Incoming
+TCF messages are suspended while the safe queue is non-empty and are
+resumed when the last safe queue entry is handled.</p>
+<p>Files:</p>
+<ul>
+        <li>runctrl.c</li>
+        <li>runctrl.h</li>
+</ul>
+
+<h3>System Monitoring</h3>
+
+<p>This module provides system level monitoring
+information, similar to the UNIX top or Windows task manager.</p>
+<p>Files:</p>
+<ul>
+        <li>sysmon.c</li>
+        <li>sysmon.h</li>
+</ul>
+
+<h3>Agent Diagnostics</h3>
+
+<p>This service is used to do end-to-end self test
+from the host to the target.</p>
+<p>Files:</p>
+<ul>
+        <li>diagnostics.c</li>
+        <li>diagnostics.h</li>
+</ul>
+
+<h1><a name='Context'>Executable Context Handling</a></h1>
+
+<p>This module handles process/thread OS contexts and
+their state machine. All ptrace() handling is isolated to here.</p>
+<p>Files:</p>
+<ul>
+        <li>context.c</li>
+        <li>context.h</li>
+</ul>
+
+<h1><a name='EventQueue'>Agent Event Queue<a></h1>
+
+<p>This module implements the main event queue
+dispatch and queuing. All events are processed by a single thread.
+Any thread can queue new events.</p>
+<p>Files:</p>
+<ul>
+        <li>events.c</li>
+        <li>events.h</li>
+</ul>
+
+<h1><a name='Misc'>Misc</a></h1>
+
+<h3>Command line interpreter</h3>
+
+<p>The module allows a user to interact with agent. Current implementation of command line interpreter is incomplete.</p>
+<p>Files:</p>
+<ul>
+        <li>cmdline.c</li>
+        <li>cmdline.h</li>
+</ul>
+
+<h3>Error message display</h3>
+
+<p>This module defines agent error codes in addition to system codes defined in errno.h</p>
+<p>Files:</p>
+<ul>
+        <li>errors.c</li>
+        <li>errors.h</li>
+</ul>
+
+<h3>Exception Handling</h3>
+
+<p>Exception handling. Functionality is similar to C++ try/catch.</p>
+<p>Files:</p>
+<ul>
+        <li>exceptions.c</li>
+        <li>exceptions.h</li>
+</ul>
+
+<h3>JSON Library</h3>
+
+<p>The module contains utility functions for parsing and generating of JSON text.
+TCF standard services use JSON as messages format. See <a href='TCF Specification.html#JSON'>JSON - Preferred Marshaling</a>
+for JSON description.</p>
+<p>Files:</p>
+<ul>
+        <li>json.c</li>
+        <li>json.h</li>
+</ul>
+
+<h3>Double Linked List</h3>
+
+<p>Utilitity module to support double linked lists.</p>
+<p>Files:</p>
+<ul>
+        <li>link.h</li>
+</ul>
+
+<h3>Host OS Abstraction</h3>
+
+<p>Machine and OS dependend definitions.
+This module implements host OS abstraction layer that helps make
+agent code portable between Linux, Windows, VxWorks and potentially other OSes.</p>
+<p>Files:</p>
+<ul>
+        <li>mdep.c</li>
+        <li>mdep.h</li>
+</ul>
+
+<h3>Malloc Abstraction</h3>
+
+<p>Provides local versions of malloc(), realloc() and free().</p>
+<p>Files:</p>
+<ul>
+        <li>myalloc.c</li>
+        <li>myalloc.h</li>
+</ul>
+
+<h3>Proxy</h3>
+
+<p>Proxy service should allow tunneling of TCF messages to another target on behalf of a client.
+This service intended to be used when a client has no direct access to a target.</p>
+<p>Files:</p>
+<ul>
+        <li>proxy.c</li>
+        <li>proxy.h</li>
+</ul>
+
+<h3>Test Application</h3>
+
+<p>Test application is used by Diagnostics service to run various tests.</p>
+<p>Files:</p>
+<ul>
+        <li>test.c</li>
+        <li>test.h</li>
+</ul>
+
+<h3>Debug Logging</h3>
+
+<p>The module implements logging and tracing that is mostly intended for debugging of the agent.</p>
+<p>Files:</p>
+<ul>
+        <li>trace.c</li>
+        <li>trace.h</li>
+</ul>
+
+<h1><a name='Architecture'>Architecture</a></h1>
+
+<p><img SRC="TCF%20Architecture.png" NAME="graphics1" ALIGN=BOTTOM WIDTH=647 HEIGHT=359 BORDER=0></p>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Project.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,135 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
+<HTML lang=en-us>
+<HEAD>
+<TITLE>Target Communication Framework</TITLE>
+</HEAD>
+
+<BODY>
+
+<H1>Target Communication Framework project</H1>
+
+<P>
+<H2><A name='Index'></A>Index</H2>
+
+<UL>
+  <LI><A href="#Summary">Summary</A> 
+  <LI><A href="#Goals">Goals</A> 
+  <LI><A href="#Features">Features</A> 
+  <LI><A href="#Agent">Reference implementation of a target agent</A>
+  <LI><A href="#Debugger">Prototype of a debugger based on Eclipse Debug Framework and TCF</A>
+  <LI><A href="#RSE">Prototype of a system monitor and remote file access based on Remote System Explorer and TCF</A>
+</UL>
+
+<P>
+<H2><A name='Summary'></A>Summary </H2>
+
+<P>Today almost every device software development tool on the market has its own 
+method of communication with target system. Communication methods often conflict 
+with each other, require individual setup, configuration and maintenance, impose 
+all kinds of unnecessary limitations. Target Communication Framework is designed 
+to establish common ground in the area of communication protocols between 
+development tools and embedded devices. 
+
+<P>
+<H2><A name='Goals'></A>Goals </H2>
+<P>
+<UL>
+  <LI>Universal, extensible, simple, lightweight, vendor agnostic framework for 
+  tools and targets to communicate for purpose of debugging, profiling, code 
+  patching and other device software development needs. 
+  <LI>Single configuration per target (not per tool per target as today in most 
+  cases), or no configuration when possible. 
+  <LI>Small overhead and footprint on target side. </LI></UL>
+<P>
+
+<H2><A name='Features'></A>Features </H2>
+<P><A href="TCF Specification.html">Target Communication Framework Specification</A> is a document 
+describing design goals, requirements and format of TCF communication protocol, 
+as well as framework API and software design considerations. 
+<P>TCF communication model is based on the idea of services. A service is a group 
+of related commands, events and semantics. A service can be discovered, 
+added or removed as a group at communication endpoint. Service definitions are 
+not part of the framework specification, and new services are expected to be 
+defined by developers of tools and target agents. However, standardization of 
+common services is needed to achieve certain level of compatibility of 
+tools/targets, see <A href="TCF Services.html">TCF Services Specification</A>
+as starting point of this work. 
+
+<H2><A name='Agent'></A>Reference implementation of a target agent</H2>
+
+<P>Current reference implementation of TCF target agents is fully functional, 
+can run on Windows, Linux and VxWorks.  On Linux it is implemented 
+using PTRACE, on VxWorks is uses vxdbgLib, on Windows it uses Debug API and dbghelp.dll. 
+The agent provides the following services: 
+<UL>
+    <LI>Run Control - provides threads and processes run control functionality 
+    sufficient for debugging of user space programs.
+    <LI>Breakpoints - provides basic breakpoints support.
+
+    <LI>Registers - allows inspection and modification of CPU registers.
+
+    <LI>Stack Trace - execution thread stack back-tracing.
+
+    <LI>Memory - program memory access.
+
+    <LI>Processes - provides access to the target OS's process 
+    information, allows starting new and terminating existing processes,
+    and allows attaching and detaching processes for debugging.
+
+    <LI>Line Numbers - provides mapping between locations in the source files
+    and corresponding machine instruction addresses in the executable object.
+    Implemented for Linux and Windows, not supported on VxWorks.
+
+    <LI>Sys Monitor - provides list of processes, process attributes and 
+    CPU/memory utilization data. On Linux it is implemented using /proc file 
+    system, on Windows and VxWorks it is not currently supported. 
+
+    <LI>File System - provides access to remote file system.
+    
+    <LI>Streams - a generic service to support streaming of data between host and target.
+
+    <LI>Diagnostics - allows testing of communication channel and agent 
+    functionality.
+</UL>
+
+<P>The agent code is designed to be easily extensible by adding new command 
+handler implementations. The code separates machine dependences, common TCF 
+logic and service implementations, which allows easy porting to a new OS or a 
+target and reconfiguring of the agent for specific needs. The code is written in 
+ANSI C. See <A href="TCF Linux Agent Prototype.html">TCF Linux Agent Prototype</A>
+for more details about the agent code. 
+
+<H2><A name='Debugger'></A>Prototype of a debugger based on Eclipse Debug Framework and TCF</H2>
+
+<P>The prototype code connects Eclipse Debug Framework and Target Communication 
+Framework. It allows to launch Eclipse debug session by connecting to a target 
+running TCF agent, and then perform basic debugging tasks, like resuming, 
+suspending, single-stepping, setting/removing breakpoints, etc.
+<P>The prototype launch configuration autodetects TCF targets on a local network 
+and allows a user to connect to a target by simply selecting it from a list 
+without a need for any further configuration or setup. TCF launch configuration 
+dialog also offers controls to run a built-in diagnostics on a selecting target, 
+which perform stress testing of communication channel, agent and target itself: 
+<P><IMG alt="TCF launch configuration dialog" src="TCF_Launch_Dialog.jpg"> 
+
+<P>The prototype makes use of flexible debug model element hierarchy support, 
+which is available in Eclipse debug framework since Eclipse 3.2. The flexible 
+hierarchy allows debugger views to be "data driven" or, in other words, dynamically 
+adapt to a given targets capabilities and structure, without a need to modify 
+debugger code to support a new target.
+ 
+<H2><A name='RSE'></A>Prototype of a system monitor and remote file access based on Remote System Explorer and TCF</H2>
+
+<P>Remote System Explorer is an Eclipse based component that allows users to 
+create connections to remote machines and explore their file systems, see list 
+of processes and access some other resources, like remote shells. Remote System 
+Explorer has been designed as a flexible, extensible framework to which Eclipse 
+plug-in developers can contribute their own system definitions, actions, etc. 
+<P>The prototype enables use of Processes and Files subsystems of Remote System 
+Explorer over TCF. It also extends Processes subsystem to include CPU 
+utilization data and some other process attributes in RSE views:
+<P><IMG alt="Remote System Explorer: Files subsystem over TCF" src="TCF_RSE_Files.jpg"> 
+<P><IMG alt="Remote System Explorer: Processes subsystem over TCF" src="TCF_RSE_Processes.jpg"> 
+
+</BODY>
+</HTML>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Breakpoints.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,790 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Breakpoints</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Breakpoints</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdSet'>Set</a>
+        <li><a href='#CmdAdd'>Add</a>
+        <li><a href='#CmdChange'>Change</a>
+        <li><a href='#CmdEnable'>Enable</a>
+        <li><a href='#CmdDisable'>Disable</a>
+        <li><a href='#CmdRemove'>Remove</a>
+        <li><a href='#CmdGetIDs'>Get IDs</a>
+        <li><a href='#CmdGetProperties'>Get Properties</a>
+        <li><a href='#CmdGetStatus'>Get Status</a>
+        <li><a href='#CmdGetCapabilities'>Get Capabilities</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Breakpoints Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>0.2
+        <td>2008-04-25
+        <td>Added getCapabilities
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>A breakpoint is represented by a unique identifier and set of properties.
+A breakpoint identifier (String id) needs to be unique across all hosts and targets.</p>
+ 
+<p>A breakpoint's property set is an extensible collection of named attributes,
+which define the breakpoint's location, the conditions that trigger the breakpoint, and the actions 
+executed as a result. As such, breakpoint properties are separated into three broad categories:
+<ul><b>
+    <li>Location properties
+    <li>Condition properties
+    <li>Action properties
+</b></ul>
+<p>The Location and Condition properties dictate how a breakpoint is installed and whether it should be triggered. 
+The Action properties dictate the effect of the breakpoint if it is triggered.
+
+<p>The split of Location and Condition properties is subjective and is
+not meant to describe how it is implemented.  Often, the Location
+properties dictate how a breakpoint is installed, and Condition
+properties dictate whether the breakpoint should be triggered.
+However, it is perfectly possible for an implementation to use
+Condition properties to control breakpoint installation and use
+Location properties each time the breakpoint is encountered to check
+if it should be triggered.
+
+<p>Unless stated otherwise, all Location and Condition properties have
+an implied "and" relationship.  Conceptually, a breakpoint without any
+Location or Condition properties would be triggered by any state
+change in any of the attached contexts.  Adding properties reduces the
+(sub)set of state changes that triggers the breakpoint.
+
+<p>The <b>Location properties category</b> contains the following properties:
+<p>Context defining properties specifying which context a breakpoint applies to are provided through the <a href='#propContextIds'>ContextIds</a>, 
+<a href='#propContextNames'>ContextNames </a> or the <a href='#propExecPaths'>ExecutablePaths</a> properties. 
+
+<p>The presence of certain properties defines what kind of breakpoint is installed.
+<ul>
+<li>Line Breakpoints, which are configured using the <a href='#propFile'>File</a>, 
+<a href='#propLine'>Line</a> and <a href='#propColumn'>Column</a> properties
+
+<li>Address breakpoints and watchpoints are configured using the <a href='#propLocation'>Location</a>, 
+<a href='#propAccessMode'>AccessMode</a>, <a href='#propSize'>Size</a>, 
+<a href='#propMaskValue'>MaskValue </a>and <a href='#propMask'>Mask</a> properties.
+
+<li>Temporal breakpoints which are located on a time scale are configured using the <a href='#propTime'>Time</a>, 
+<a href='#propTimeScale'>TimeScale</a>, and <a href='#propTimeUnits'> TimeUnits</a> properties.
+</ul>
+
+<p>The <a href='#propType'>Type</a> property configures whether the breakpoint should be installed as hardware or a software breakpoint.
+
+<p><b>Condition properties</b> contain the <a href='#propEnabled'>Enabled</a> property, the <a href='#propCondition'>Condition</a> and <a href='#propIgnoreCount'>IgnoreCount</a> properties.
+
+<p><b>Action properties</b> contain the <a href='#propStopGroup'>StopGroup</a> and <a href='#propTemporary'>Temporary</a> properties.
+
+<p>For each breakpoint a target agent maintains another extensible collection of named attributes:
+breakpoint status. While breakpoint properties are persistent and represent user input,
+breakpoint status reflects dynamic target agent reports about breakpoint current state,
+like actual addresses where breakpoint is installed or installation errors.
+
+<p>Every breakpoint is associated with a communication channel and when the channel is closed
+the target agent removes all corresponding breakpoints.
+Target agent should maintain separate breakpoint tables for each communication channel. 
+It is allowed to set the same breakpoint (same ID) through multiple
+channels, target agent should treat it as single breakpoint with multiple references. Such a breakpoint
+is removed when all referring channels are closed.
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdSet'>Set</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; set &bull; <i>&lt;array of breakpoints&gt;</i> &bull;
+
+<i>&lt;array of breakpoints&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;breakpoints list&gt;</i> ]
+
+<i>&lt;breakpoints list&gt;</i>
+    &rArr; <i>&lt;breakpoint data&gt;</i>
+    &rArr; <i>&lt;breakpoints list&gt;</i>, <i>&lt;breakpoint data&gt;</i>
+
+<i>&lt;breakpoint data&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p> The command downloads breakpoint data to a target agent.
+The command is intended to be used only to initialize the target's breakpoint table 
+when communication channel is open. After that, host should 
+notify the target about (incremental) changes in breakpoints data by sending
+Add, Change and Remove commands.<p>
+
+<p>Breakpoint data consists of a list of breakpoint properties. All properties are optional, except ID.
+Tools and targets can define additional properties. All provided properties need to be true for a breakpoint to be installed/hit.<br>
+A breakpoint service implementation may not change the properties set by the client.</p>
+
+<p>Predefined properties are:</p>
+<dl>
+<ul>
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propID'>"ID"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>Breakpoint ID. This is the only required property.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propeEnabled'>"Enabled"</a> : <i>&lt;boolean&gt;</i></font></b></code>
+    <dd>If true, the breakpoint is enabled. 
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propType'>"Type"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>The breakpoint type
+    <dl>
+    <ul>
+        <li><dt><code><b>"Software"</b></code> <dd> Software breakpoint.
+        <li><dt><code><b>"Hardware"</b></code> <dd> Hardware breakpoint
+        <li><dt><code><b>"Auto"</b></code> <dd> Installed breakpoint type (software/hardware) deferred to agent's discretion. This is the default breakpoint type.
+        The actual type of each breakpoint instance consequently installed is received as a status event
+    </ul>
+    </dl>
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propContextIDs'>"ContextIds"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>This property contains an array of TCF context identifiers for which this breakpoint should be installed.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propContextNames'>"ContextNames"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>This property contains an array of contexts names (such as a process/thread name) for which this breakpoint should be installed.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propExecPaths'>"ExecutablePaths"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>This property contains all the target executable paths for which this breakpoint should be installed.   
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propLocation'> "Location" </a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>If preset, defines location of the breakpoint. The expression evaluates either to a memory address 
+    or a register location.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propAccessMode'>"AccessMode"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>The access mode that will trigger the breakpoint.  Access mode can be a bitwise OR of the values below:
+    <dl>
+    <ul>
+        <li><dt><code><b>READ = 0x01</b></code> <dd>Triggered by a read from the breakpoint location
+        <li><dt><code><b>WRITE = 0x02</b></code> <dd>Triggered by a write to the breakpoint location
+        <li><dt><code><b>EXECUTE = 0x04</b></code> <dd>Triggered by an instruction execution at the breakpoint location. Whether the breakpoint is triggered before the instruction execution or after depends on the target support for this mode. This is the default for Line and Address breakpoints.
+        <li><dt><code><b>CHANGE = 0x08</b></code> <dd>Triggered by a data change (not an explicit write) at the breakpoint location
+    </ul>
+    </dl>
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propSize'>"Size"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>The number of bytes starting at the location expression to which the AccessMode triggers applies
+    
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propFile'>"File"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>Source code file name of breakpoint location.
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propLine'>"Line"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>Source code line number of breakpoint location.
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propColumn'>"Column"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>Source code column number of breakpoint location.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propMaskValue'>"MaskValue"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>A breakpoint can be qualified with a mask value which may be further refined with a mask.       
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propMask'>"Mask"</a> : <i>&lt;int&gt;</i></font></b></code>
+    <dd>A mask which is bitwise ANDed with the value accessed.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propTime'>"Time"</a> : <i>&lt;number&gt;</i></font></b></code>
+    <dd>The time value in the execution of the program at which to set the breakpoint
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propTimeScale'>"TimeScale"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>The scale for the time value
+    <dl>
+    <ul>
+       <li><dt><code><b>"Relative"</b></code> <dd> Time value in the relative time scale. This is the default value for this property.
+        In the relative time scale, the Time property may have a negative value.
+       <li><dt><code><b>"Absolute"</b></code> <dd> Time value in the absolute time scale
+     </ul>
+    </dl>
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propTimeUnits'>"TimeUnits"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>The units for the time value
+    <dl>
+    <ul>
+        <li><dt><code><b>"CycleCount"</b></code> <dd> Time value in cycles. This is the default type.
+        <li><dt><code><b>"NanoSeconds"</b></code> <dd> Time value in nano seconds
+        <li><dt><code><b>"InstructionCount"</b></code> <dd> Time value in instructions
+    </ul>
+    </dl>
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propCondition'>"Condition"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>Expression that must evaluate to true before the breakpoint is triggered.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propIgnoreCount'>"IgnoreCount"</a>: <i>&lt;int&gt;</i></font></b></code>
+    <dd>The number of times this breakpoint is to be ignored before it is triggered. The ignore count is tested after all other Location and Condition properties are validated.
+   
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name = 'propStopGroup'>"StopGroup"</a> : <i>&lt;string&gt;</i></font></b></code>
+    <dd>An array of TCF Context identifiers representing contexts to be stopped when this breakpoint is triggered.
+    This is an "Action" property that is used to stop contexts in addition to the one that triggered the breakpoint.
+
+    <li><dt><code><b><font face="Courier New" size=2 color=#333399><a name='propTemporary'>"Temporary"</a> : <i>&lt;boolean&gt;</i></font></b></code>
+    <dd>If set, results in the breakpoint being removed after it is triggered once. The default value for this property is false.
+</ul>
+</dl>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<p><b>Examples:</b></p>
+
+<p>The following properties install a hardware breakpoint at address <code>0x1000</code> for all attached contexts:</p>
+<ul>
+    <li><code>ID = "1"</code>
+    <li><code>Type = "Hardware"</code>
+    <li><code>Location = "0x1000"</code>
+</ul>
+<p>
+The following additional property limits the number of contexts for which the breakpoint by providing the ContextIDs property:<br>
+<ul>
+    <li><code>ContextIds = ["core0", "core1"]</code>
+</ul>
+<p>
+The following additional property stops the specified contexts when breakpoint 1 is hit:<br>
+<ul>
+    <li><code>StopGroup = ["core3", "core5"]</code>
+</ul>
+<p>
+The following properties set a watchpoint that stops <code>core0</code> when variable <code>fooVar</code> is read from or written to by <code>Core5</code>:
+<ul>
+    <li><code>ID = "2"</code>
+    <li><code>Type = "Hardware"</code>
+    <li><code>Location = "fooVar"</code>
+    <li><code>Size = 4</code>
+    <li><code>AccessMode = 0x01 | 0x02</code>
+    <li><code>ContextIDs = ["core5"]</code>
+    <li><code>StopGroup = ["core0"]</code>
+</ul>
+<p>
+The following additional properties further restrict the watchpoint to trigger only if an odd value is read from or written to the location.
+<ul>
+    <li><code>MaskValue = 0x00000001</code>
+    <li><code>Mask = 0x00000001</code>
+</ul>
+<p>
+The following properties set a temporal breakpoint that stops <code>core0</code> at the specified absolute time.
+<ul>
+    <li><code>ID = "3"</code>
+    <li><code>ContextIDs = ["core0"]</code>
+    <li><code>Time = 245</code>
+    <li><code>TimeUnits = "NanoSeconds"</code>
+    <li><code>TimeScale = "Absolute"</code>
+</ul>
+
+<h3><a name='CmdAdd'>Add</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; add &bull; <i>&lt;breakpoint data&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command adds a breakpoint to the target agent breakpoint table. The host should send this command when the user creates a new breakpoint</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdChange'>Change</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; change &bull; <i>&lt;breakpoint data&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command updates the breakpoint data in the target agent breakpoint table. The host should send this command when the user modifies a breakpoint</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdEnable'>Enable</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; enable &bull; <i>&lt;array of breakpoint IDs&gt;</i> &bull;
+
+<i>&lt;array of breakpoint IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;breakpoint IDs list&gt;</i> ]
+
+<i>&lt;breakpoint IDs list&gt;</i>
+    &rArr; <i>&lt;breakpoint ID&gt;</i>
+    &rArr; <i>&lt;breakpoint IDs list&gt;</i>, <i>&lt;breakpoint ID&gt;</i>
+
+<i>&lt;breakpoint ID&gt;</i>
+    &rArr; <i>&lt;string&gt;</i>
+</font></b></pre>
+
+<p>The command enables a list of breakpoints - sets breakpoint property "Enabled" to true.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdDisable'>Disable</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; disable &bull; <i>&lt;array of breakpoint IDs&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command disables a list of breakpoints - sets breakpoint property "Enabled" to false.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRemove'>Remove</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; remove &bull; <i>&lt;array of breakpoint IDs&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command removes a list of breakpoints. Host should send this command when user deletes breakpoints.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetIDs'>Get IDs</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; getIDs &bull;
+</font></b></pre>
+
+<p>The command uploads IDs of breakpoints known to target agent,
+including breakpoints that are set through different communication
+channels.  It is up to the client to keep track of which breakpoints
+it has set such that it can know which breakpoint are set by other
+channels.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of breakpoint IDs&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetProperties'>Get Properties</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; getProperties &bull; <i>&lt;string: breakpoint ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command uploads the properties of the given breakpoint from the target agent breakpoint table.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;breakpoint data&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetStatus'>Get Status</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; getStatus &bull; <i>&lt;string: breakpoint ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command uploads the status of given the breakpoint from the target agent.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;breakpoint status&gt;</i> &bull;
+
+<i>&lt;breakpoint status&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Breakpoint status consists of a list of status properties. All properties are optional.
+Tools and targets can define additional properties. 
+Setting any properties that are not supported by or unknown to the service implementation will yield an error, 
+which is reported in the Error property of the breakpoint status object.</p>
+
+<p>Predefined properties are:</p>
+
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Instances" : <i>&lt;array of instance status data&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Error" : <i>&lt;string&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"File" : <i>&lt;string&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Line" : <i>&lt;int&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Column" : <i>&lt;int&gt;</i></font></b></code>
+</ul>
+
+
+A breakpoint installation can lead to zero or more installed instances of the breakpoints. Properties associated with each
+of those installed instances (or error information in case there was a failure installing an instance) are provided
+in a list of instance status data objects
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;array of instance status data&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;Instance status data list&gt;</i> ]
+
+<i>&lt;Instance status data list&gt;</i>
+    &rArr; <i>&lt;Instance status data&gt;</i>
+    &rArr; <i>&lt;Instance staus data list&gt;</i>, <i>&lt;Instance status data&gt;</i>
+  
+<i>&lt;Instance status data&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Instance status data consists of a list of properties pertaining to each installed instance of the breakpoint.
+
+<p>Predefined properties are:
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Error" : <i>&lt;string&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"BreakpointType" : <i>&lt;string&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"LocationContext" : <i>&lt;string&gt;</i></font></b></code>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Address" : <i>&lt;string&gt;</i></font></b></code>
+</ul>
+
+<h3><a name='CmdGetCapabilities'>Get Capabilities</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Breakpoints &bull; getCapabilities &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command reports breakpoint service capabilities to clients so they
+can adjust to different implementations of the service.
+When called with a null ("") context ID the global capabilities are returned,
+otherwise context specific capabilities are returned.  A special capability
+property is used to indicate that all child contexts have the same
+capabilities.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;service capabilities&gt;</i> &bull;
+
+<i>&lt;service capabilities&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Service capabilities consist of a list of properties. All properties are optional.
+Tools and targets can define additional properties. Predefined properties are:</p>
+
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string: context ID&gt;</i></font></b></code>
+    - ID of a context that was used to query capabilities
+    <li><code><b><font face="Courier New" size=2 color=#333399>"HasChildren" : <i>&lt;boolean&gt;</i></font></b></code>
+    - if true, children of the context can have different capabilities
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Address" : <i>&lt;boolean&gt;</i></font></b></code>
+    - if true, "Address" breakpoint property is supported
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Condition" : <i>&lt;boolean&gt;</i></font></b></code>
+    - if true, "Condition" breakpoint property is supported
+    <li><code><b><font face="Courier New" size=2 color=#333399>"FileLine" : <i>&lt;boolean&gt;</i></font></b></code>
+    - if true, "File", "Line" and "Column" breakpoint properties are supported
+</ul>
+
+<h2><a name='Events'>Events</a></h2>
+
+<p>Breakpoints service events are sent to notify clients about breakpoint properties and status changes.
+Note that contextAdded, contextChanged and contextRemoved events carry exactly same set
+of breakpoint properties that was sent by a client to a target. The purpose of these events is to
+let all clients know about breakpoints that were created by other clients.</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Breakpoints &bull; status &bull; <i>&lt;string: breakpoint ID&gt;</i> &bull; <i>&lt;breakpoint status&gt;</i> &bull;
+E &bull; Breakpoints &bull; contextAdded &bull; <i>&lt;array of breakpoints&gt;</i> &bull;
+E &bull; Breakpoints &bull; contextChanged &bull; <i>&lt;array of breakpoints&gt;</i> &bull;
+E &bull; Breakpoints &bull; contextRemoved &bull; <i>&lt;array of breakpoint IDs&gt;</i> &bull;
+</font></b></pre>
+
+<dl>
+    <dt><b>status</b>
+        <dd>Is sent when breakpoint status changes.
+    <dt><b>contextAdded</b>
+        <dd>Is sent when a new breakpoints are added.
+    <dt><b>contextChanged</b>
+        <dd>Is sent when breakpoint properties change.
+    <dt><b>contextRemoved</b>
+        <dd>Is sent when breakpoints are removed.
+</dl>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#3F5FBF>/**
+ * Breakpoint is represented by unique identifier and set of properties.
+ * Breakpoint identifier (String id) needs to be unique across all hosts and targets.
+ * 
+ * Breakpoint properties (Map&lt;String,Object>) is extensible collection of named attributes,
+ * which define breakpoint location and behavior. This module defines some common
+ * attribute names (see PROP_*), host tools and target agents may support additional attributes.
+ * 
+ * For each breakpoint a target agent maintains another extensible collection of named attributes:
+ * breakpoint status (Map&lt;String,Object>, see STATUS_*). While breakpoint properties are
+ * persistent and represent user input, breakpoint status reflects dynamic target agent reports
+ * about breakpoint current state, like actual addresses where breakpoint is installed or installation errors.
+ */</font>
+<font color=#7F0055>public interface</font> IBreakpoints <font color=#7F0055>extends</font> IService {
+
+    <font color=#3F5FBF>/**
+     * Service name.
+     */</font>
+    <font color=#7F0055>static final</font> String NAME = "Breakpoints";
+
+    <font color=#3F5FBF>/**
+     * Breakpoint property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        PROP_ID = "ID",                           // String
+        PROP_ENABLED = "Enabled",                 // Boolean
+        PROP_TYPE = "BreakpointType",             // String
+        PROP_CONTEXTNAMES = "ContextNames",       // Array
+        PROP_CONTEXTIDS = "ContextIds",           // Array
+        PROP_EXECUTABLEPATHS = "ExecPaths",       // Array
+        PROP_LOCATION = "Location",               // String
+        PROP_SIZE = "Size",                       // Number
+        PROP_ACCESSMODE = "AccessMode",           // Number
+        PROP_FILE = "File",                       // String
+        PROP_LINE = "Line",                       // Number
+        PROP_COLUMN = "Column",                   // Number
+        PROP_PATTERN = "MaskValue",               // Number
+        PROP_MASK = "Mask",                       // Number
+        PROP_STOP_GROUP = "StopGroup",            // Array
+        PROP_IGNORECOUNT = "IgnoreCount",         // Number
+        PROP_TIME = "Time",                       // Number
+        PROP_SCALE = "TimeScale",                 // String
+        PROP_UNITS = "TimeUnits",                 // String
+        PROP_CONDITION = "Condition",             // String
+        PROP_TEMPORARY = "Temporary";             // Boolean
+
+    <font color=#3F5FBF>/**
+     * BreakpointType values 
+     */</font>
+    <font color=#7F0055>static final</font> String
+        TYPE_RELATIVE = "Software",
+        TYPE_ABSOLUTE = "Hardware",
+        TYPE_AUTO = "Auto";
+
+    <font color=#3F5FBF>/** 
+     * AccessMode values 
+     */ </font>
+    <font color=#7F0055>static final</font> int 
+        ACCESSMODE_READ    = 0x01,
+        ACCESSMODE_WRITE   = 0x02, 
+        ACCESSMODE_EXECUTE = 0x04,
+        ACCESSMODE_CHANGE  = 0x08;
+
+    <font color=#3F5FBF>/**
+     * TimeScale values 
+     */</font>
+    <font color=#7F0055>static final</font> String 
+        TIMESCALE_RELATIVE = "Relative",
+        TIMESCALE_ABSOLUTE = "Absolute";
+    
+    <font color=#3F5FBF>/**
+     * TimeUnits values 
+     */</font>
+    <font color=#7F0055>static final</font> String
+        TIMEUNIT_NSECS = "Nanoseconds",
+        TIMEUNIT_CYCLE_COUNT = "CycleCount",
+        TIMEUNIT_INSTRUCTION_COUNT = "InstructionCount";
+
+    <font color=#3F5FBF>/**
+     * Breakpoint status field names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        STATUS_INSTALLED = "Installed", // Array of addresses
+        STATUS_ERROR = "Error",         // String
+        STATUS_FILE = "File",           // String
+        STATUS_LINE = "Line",           // Number
+        STATUS_COLUMN = "Column";       // Number
+    
+    <font color=#3F5FBF>/**
+     * Breakpoint service capabilities.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        CAPABILITY_CONTEXT_ID = "ID",                   // String
+        CAPABILITY_HAS_CHILDREN = "HasChildren",        // Boolean
+        CAPABILITY_ADDRESS = "Address",                 // Boolean
+        CAPABILITY_CONDITION = "Condition",             // Boolean
+        CAPABILITY_FILE_LINE = "FileLine";              // Boolean
+
+    <font color=#3F5FBF>/**
+     * Call back interface for breakpoint service commands.
+     */</font>
+    <font color=#7F0055>interface</font> DoneCommand {
+        <font color=#7F0055>void</font> doneCommand(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Download breakpoints data to target agent.
+     * The command is intended to be used only to initialize target breakpoints table 
+     * when communication channel is open. After that, host should 
+     * notify target about (incremental) changes in breakpoint data by sending
+     * add, change and remove commands.
+     * 
+     * @param properties - array of breakpoints.
+     * @param done - command result call back object.
+     */</font>
+    IToken set(Map&lt;String,Object&gt;[] properties, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Called when breakpoint is added into breakpoints table.
+     * @param properties - breakpoint properties.
+     * @param done - command result call back object.
+     */</font>
+    IToken add(Map&lt;String,Object&gt; properties, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Called when breakpoint properties are changed.
+     * @param properties - breakpoint properties.
+     * @param done - command result call back object.
+     */</font>
+    IToken change(Map&lt;String,Object&gt; properties, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Tell target to change (only) PROP_ENABLED breakpoint property 'true'.
+     * @param ids - array of enabled breakpoint identifiers.
+     * @param done - command result call back object.
+     */</font>
+    IToken enable(String[] ids, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Tell target to change (only) PROP_ENABLED breakpoint property to 'false'.
+     * @param ids - array of disabled breakpoint identifiers.
+     * @param done - command result call back object.
+     */</font>
+    IToken disable(String[] ids, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Tell target to remove breakpoint.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     */</font>
+    IToken remove(String[] ids, DoneCommand done);
+    
+    <font color=#3F5FBF>/**
+     * Upload IDs of breakpoints known to target agent.
+     * @param done - command result call back object.
+     */</font>
+    IToken getIDs(DoneGetIDs done);
+
+    <font color=#7F0055>interface</font> DoneGetIDs {
+        <font color=#7F0055>void</font> doneGetIDs(IToken token, Exception error, String[] ids);
+    }
+
+    <font color=#3F5FBF>/**
+     * Upload properties of given breakpoint from target agent breakpoint table.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     */</font>
+    IToken getProperties(String id, DoneGetProperties done);
+
+    <font color=#7F0055>interface</font> DoneGetProperties {
+        <font color=#7F0055>void</font> doneGetProperties(IToken token, Exception error, Map&lt;String,Object&gt; properties);
+    }
+
+    <font color=#3F5FBF>/**
+     * Upload status of given breakpoint from target agent.
+     * @param id - unique breakpoint identifier.
+     * @param done - command result call back object.
+     */</font>
+    IToken getStatus(String id, DoneGetStatus done);
+
+    <font color=#7F0055>interface</font> DoneGetStatus {
+        <font color=#7F0055>void</font> doneGetStatus(IToken token, Exception error, Map&lt;String,Object&gt; status);
+    }
+
+    <font color=#3F5FBF>/**
+     * Report breakpoint service capabilities to clients so they
+     * can adjust to different implementations of the service.
+     * When called with a null ("") context ID the global capabilities are returned,
+     * otherwise context specific capabilities are returned.  A special capability
+     * property is used to indicate that all child contexts have the same
+     * capabilities.
+     * @param id - a context ID or null.
+     * @param done - command result call back object.
+     */</font>
+    IToken getCapabilities(String id, DoneGetCapabilities done);
+
+    <font color=#7F0055>interface</font> DoneGetCapabilities {
+        void</font> doneGetCapabilities(IToken token, Exception error, Map&lt;String,Object&gt; capabilities);
+    }
+
+    <font color=#3F5FBF>/**
+     * Breakpoints service events listener.
+     * Note that contextAdded, contextChanged and contextRemoved events carry exactly same set
+     * of breakpoint properties that was sent by a client to a target. The purpose of these events is to
+     * let all clients know about breakpoints that were created by other clients.
+     */</font>
+    <font color=#7F0055>interface</font> BreakpointsListener {
+
+        <font color=#3F5FBF>/**
+         * Called when breakpoint status changes.
+         * @param id - unique breakpoint identifier.
+         * @param status - breakpoint status.
+         */</font>
+        <font color=#7F0055>void</font> breakpointStatusChanged(String id, Map&lt;String,Object&gt; status);
+
+        <font color=#3F5FBF>/**
+         * Called when a new breakpoints are added.
+         * @param bps - array of breakpoints.
+         */</font>
+        <font color=#7F0055>void</font> contextAdded(Map&lt;String,Object&gt;[] bps);
+
+        <font color=#3F5FBF>/**
+         * Called when breakpoint properties change.
+         * @param bps - array of breakpoints.
+         */</font>
+        <font color=#7F0055>void</font> contextChanged(Map&lt;String,Object&gt;[] bps);
+
+        <font color=#3F5FBF>/**
+         * Called when breakpoints are removed.
+         * @param ids - array of breakpoint IDs.
+         */</font>
+        <font color=#7F0055>void</font> contextRemoved(String[] ids);
+    }
+
+    <font color=#3F5FBF>/**
+     * Add breakpoints service event listener.
+     * @param listener - object that implements BreakpointsListener interface.
+     */</font>
+    <font color=#7F0055>void</font> addListener(BreakpointsListener listener);
+
+    <font color=#3F5FBF>/**
+     * Remove breakpoints service event listener.
+     * @param listener - object that implements BreakpointsListener interface.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(BreakpointsListener listener);
+}
+</pre>
+
+</body>
+</html>
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - File System.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,1171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - File System</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - File System</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#ReqSync'>Request Synchronization and Reordering</a>
+    <li><a href='#FileNames'>File Names</a>
+    <li><a href='#FileModes'>File Open Modes</a>
+    <li><a href='#FileAttributes'>File Attributes</a>
+    <li><a href='#ErrorCodes'>Error Codes</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdOpen'>open</a>
+        <li><a href='#CmdClose'>close</a>
+        <li><a href='#CmdRead'>read</a>
+        <li><a href='#CmdWrite'>write</a>
+        <li><a href='#CmdStat'>stat</a>
+        <li><a href='#CmdLStat'>lstat</a>
+        <li><a href='#CmdFStat'>fstat</a>
+        <li><a href='#CmdSetStat'>setstat</a>
+        <li><a href='#CmdFSetStat'>fsetstat</a>
+        <li><a href='#CmdOpenDir'>opendir</a>
+        <li><a href='#CmdReadDir'>readdir</a>
+        <li><a href='#CmdMkDir'>mkdir</a>
+        <li><a href='#CmdRmDir'>rmdir</a>
+        <li><a href='#CmdRoots'>roots</a>
+        <li><a href='#CmdRemove'>remove</a>
+        <li><a href='#CmdRealPath'>realpath</a>
+        <li><a href='#CmdRename'>rename</a>
+        <li><a href='#CmdReadLink'>readlink</a>
+        <li><a href='#CmdSymLink'>symlink</a>
+        <li><a href='#CmdSymLink'>copy</a>
+        <li><a href='#CmdSymLink'>user</a>
+    </ul>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>File System Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>File System service provides file transfer (and more generally file
+system access) functionality in TCF. The service design is
+derived from SSH File Transfer Protocol specifications.</p>
+ 
+<h2><a name='ReqSync'>Request Synchronization and Reordering</a></h2>
+
+<p>The protocol and implementations MUST process requests relating to
+the same file in the order in which they are received.  In other
+words, if an application submits multiple requests to the server, the
+results in the responses will be the same as if it had sent the
+requests one at a time and waited for the response in each case.  For
+example, the server may process non-overlapping read/write requests
+to the same file in parallel, but overlapping reads and writes cannot
+be reordered or parallelized.  However, there are no ordering
+restrictions on the server for processing requests from two different
+file transfer connections.  The server may interleave and parallelize
+them at will.</p>
+
+<p>There are no restrictions on the order in which responses to
+outstanding requests are delivered to the client, except that the
+server must ensure fairness in the sense that processing of no
+request will be indefinitely delayed even if the client is sending
+other requests so that there are multiple outstanding requests all
+the time.</p>
+
+<p>There is no limit on the number of outstanding (non-acknowledged)
+requests that the client may send to the server.  In practice this is
+limited by the buffering available on the data stream and the queuing
+performed by the server.  If the server's queues are full, it should
+not read any more data from the stream, and flow control will prevent
+the client from sending more requests.</p>
+
+<h2><a name='FileNames'>File Names</a></h2>
+
+<p>This protocol represents file names as strings.  File names are
+assumed to use the slash ('/') character as a directory separator.</p>
+
+<p>File names starting with a slash are "absolute", and are relative to
+the root of the file system.  Names starting with any other character
+are relative to the user's default directory (home directory). Client
+can use 'user()' command to retrieve current user home directory.</p>
+
+<p>Servers SHOULD interpret a path name component ".." as referring to
+the parent directory, and "." as referring to the current directory.
+If the server implementation limits access to certain parts of the
+file system, it must be extra careful in parsing file names when
+enforcing such restrictions.  There have been numerous reported
+security bugs where a ".." in a path name has allowed access outside
+the intended area.</p>
+
+<p>An empty path name is valid, and it refers to the user's default
+directory (usually the user's home directory).</p>
+
+<p>Otherwise, no syntax is defined for file names by this specification.
+Clients should not make any other assumptions; however, they can
+splice path name components returned by readdir() together
+using a slash ('/') as the separator, and that will work as expected.</p>
+
+<h2><a name='FileModes'>File Open Modes</a></h2>
+
+<p>File open mode is bitwise OR of mode flags:</p>
+
+<dl>
+    <dt><code>TCF_O_READ = 0x00000001</code>
+    <dd>Open the file for reading.
+
+    <dt><code>TCF_O_WRITE = 0x00000002</code>
+    <dd>Open the file for writing. If both this and TCF_O_READ are
+    specified, the file is opened for both reading and writing.
+
+    <dt><code>TCF_O_APPEND = 0x00000004</code>
+    <dd>Force all writes to append data at the end of the file.
+
+    <dt><code>TCF_O_CREAT = 0x00000008</code>
+    <dd>If this flag is specified, then a new file will be created if one
+    does not already exist (if TCF_O_TRUNC is specified, the new file will
+    be truncated to zero length if it previously exists).
+
+    <dt><code>TCF_O_TRUNC = 0x00000010</code>
+    <dd>Forces an existing file with the same name to be truncated to zero
+    length when creating a file by specifying TCF_O_CREAT.
+    TCF_O_CREAT MUST also be specified if this flag is used.
+    
+    <dt><code>TCF_O_EXCL = 0x00000020</code>
+    <dd>Causes the request to fail if the named file already exists.
+    TCF_O_CREAT MUST also be specified if this flag is used.
+</dl>
+
+<h2><a name='FileAttributes'>File Attributes</a></h2>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;file attributes&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>All attributes are optional.
+Tools and targets can define additional attributes. Predefined attributes are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Size" : <i>&lt;int&gt;</i></font></b></code>
+    - file size in bytes
+    <li><code><b><font face="Courier New" size=2 color=#333399>"UID" : <i>&lt;int&gt;</i></font></b></code>
+    - file owner user ID
+    <li><code><b><font face="Courier New" size=2 color=#333399>"GID" : <i>&lt;int&gt;</i></font></b></code>
+    - file owner group ID
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Permissions" : <i>&lt;int&gt;</i></font></b></code>
+    - file access permissions
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ATime" : <i>&lt;int&gt;</i></font></b></code>
+    - file last access time
+    <li><code><b><font face="Courier New" size=2 color=#333399>"MTime" : <i>&lt;int&gt;</i></font></b></code>
+    - file last modification time
+</ul>
+
+<h2><a name='ErrorCodes'>Error codes</a></h2>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+
+<p>Currently, the following values are defined for service specific error codes (other values may be
+defined by future versions of this protocol):</p>
+
+<dl>
+    <dt><code>STATUS_EOF = 0x10001</code>
+    <dd>Indicates end-of-file condition; for 'read' it means that no
+    more data is available in the file, and for 'readdir' it
+    indicates that no more files are contained in the directory.
+
+    <dt><code>STATUS_NO_SUCH_FILE = 0x10002</code>
+    <dd>This code is returned when a reference is made to a file which
+    should exist but doesn't.
+
+    <dt><code>STATUS_PERMISSION_DENIED = 0x10003</code>
+    <dd>is returned when the authenticated user does not have sufficient
+    permissions to perform the operation.
+</dl>
+
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdOpen'>open</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; open &bull; <i>&lt;string: file name&gt;</i> &bull; <i>&lt;int: mode&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command opens or creates a file on a remote system. If mode contains TCF_O_CREAT then new file is created, otherwise exsting
+file is opened. If the file is created, file attributes is looked up for UID, GID and permissions. If no attribute value is found in
+the command parameters, a default value is used.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;file handle&gt;</i> &bull;
+
+<i>&lt;file handle&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;string&gt;</i>
+</font></b></pre>
+
+<p>On success, the replay contains open file handle. The handle is encoded as a string of characters. Client should never try
+to decode the string, but should use it as is to issue further file access commands. Client should close the file when it is
+not needed any more. Server should close all files that were left open after client connection was closed ot terminated.</p>
+
+<h3><a name='CmdClose'>close</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; close &bull; <i>&lt;string: file handle&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command closes a handle, which was open by 'open' or 'opendir' commands.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRead'>read</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; read &bull; <i>&lt;string: file handle&gt;</i> &bull; <i>&lt;int: offset&gt;</i> &bull; <i>&lt;int: size&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command reads bytes from an open file.
+In response to this request, the server will read as many bytes as it
+can from the file (up to `size'), and return them in a byte array.
+If an error occurs or EOF is encountered, the server may return
+fewer bytes then requested. Replay argument 'error report'
+will be not null in case of error, and argument 'eof' will be
+true in case of EOF. For normal disk files, it is guaranteed
+that this will read the specified number of bytes, or up to end of file
+or error. For e.g. device files this may return fewer bytes than requested.</p>
+
+<p>If 'offset' < 0 then reading will start from current position in the file.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;string: data&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;boolean: eof&gt;</i> &bull;
+</font></b></pre>
+
+<p><i>&lt;string: data&gt;</i> is Base64 encoded byte array of file data. Number of bytes is determined by the string length.
+'eof' is true when 'data' contains all available bytes up to the end of the file.</p>
+
+<h3><a name='CmdWrite'>write</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; write &bull; <i>&lt;string: file handle&gt;</i> &bull; <i>&lt;int: offset&gt;</i> &bull; <i>&lt;string: data&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command writes bytes into an open file.
+The write will extend the file if writing beyond the end of the file.
+It is legal to write way beyond the end of the file; the semantics
+are to write zeroes from the end of the file to the specified offset
+and then the data. <i>&lt;string: data&gt;</i> is Base64 encoded array of data bytes.</p>
+
+<p>If 'offset' < 0 then writing will start from current position in the file.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdStat'>stat</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; stat &bull; <i>&lt;string: file name&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves file attributes.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdLStat'>lstat</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; lstat &bull; <i>&lt;string: file name&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves file attributes.
+Unlike 'stat', 'lstat' does not follow symbolic links.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdFStat'>fstat</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; fstat &bull; <i>&lt;string: file handle&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves file attributes for an open file (identified by the file handle).</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdSetStat'>setstat</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; setstat &bull; <i>&lt;string: file name&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command sets file attributes.
+This request is used for operations such as changing the ownership,
+permissions or access times, as well as for truncating a file.
+An error will be returned if the specified file system object does
+not exist or the user does not have sufficient rights to modify the
+specified attributes.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdFSetStat'>fsetstat</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; fsetstat &bull; <i>&lt;string: file handle&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command sets file attributes for an open file (identified by the file handle).
+This request is used for operations such as changing the ownership,
+permissions or access times, as well as for truncating a file.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdOpenDir'>opendir</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; opendir &bull; <i>&lt;string: path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command opens a directory for reading.
+Once the directory has been successfully opened, files (and
+directories) contained in it can be listed using 'readdir' requests.
+When the client no longer wishes to read more names from the
+directory, it SHOULD call 'close' for the handle.  The handle
+should be closed regardless of whether a read errors have occurred or not.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;file handle&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdReadDir'>readdir</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; readdir &bull; <i>&lt;string: file handle&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command returns one
+or more file names with full file attributes for each file.  The
+client should call 'readdir' repeatedly until it has found the
+file it is looking for or until the server responds with a
+message indicating an error or end of file. The client should then
+close the handle using the 'close' request.
+Note: directory entries "." and ".." are NOT included into readdir()
+response.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;array of directory entries&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;boolean: eof&gt;</i> &bull;
+
+<i>&lt;array of directory entries&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;directory entry list&gt;</i> ]
+  
+<i>&lt;directory entry list&gt;</i>
+    &rArr; <i>&lt;directory entry&gt;</i>
+    &rArr; <i>&ltdirectory entry list&gt;</i> , <i>&lt;directory entry&gt;</i>
+
+<i>&lt;directory entry&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Directory entry attributes are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"FileName" : <i>&lt;string&gt;</i></font></b></code>
+    - a file name being returned, it will be a relative name within the directory,
+    without any path components.
+    <li><code><b><font face="Courier New" size=2 color=#333399>"LongName" : <i>&lt;string&gt;</i></font></b></code>
+    - a human readable, expanded format for the file name, similar to what
+    is returned by "ls -l" on Unix systems
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Attrs" : <i>&lt;file attributes&gt;</i></font></b></code>
+    - the attributes of the file as described in Section <a href='#FileAttributes'>File Attributes</a>.
+</ul>
+
+<h3><a name='CmdMkDir'>mkdir</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; mkdir &bull; <i>&lt;string: directory path&gt;</i> &bull; <i>&lt;file attributes&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command creates a directory on the server.
+<i>&lt;string: directory path&gt;</i> specifies the directory to be created.
+<i>&lt;file attributes&gt;</i> specifies new directory attributes.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRmDir'>rmdir</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; rmdir &bull; <i>&lt;string: directory path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command removes a directory.
+An error will be returned if no directory
+with the specified path exists, or if the specified directory is not
+empty, or if the path specified a file system object other than a
+directory. <i>&lt;string: directory path&gt;</i> - specifies the directory to be removed.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRoots'>roots</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; roots &bull;
+</font></b></pre>
+
+<p>The command retrieves file system roots - top level file system objects.
+UNIX file system can report just one root with path "/". Other types of systems
+can have more the one root. For example, Windows server can return multiple roots:
+one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
+the service must use forward slash as directory separator, and must start 
+absolute path with "/". Server should implement proper translation of
+protocol file names to OS native names and back.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of directory entries&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRemove'>remove</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; remove &bull; <i>&lt;string: path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command removes a file or symbolic link.
+This request cannot be used to remove directories.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRealPath'>realpath</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; realpath &bull; <i>&lt;string: path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command canonicalizes any given path name to an absolute path.
+This is useful for converting path names containing ".." components or
+relative pathnames without a leading slash into absolute paths.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;string: path&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRename'>rename</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; rename &bull; <i>&lt;string: old path&gt;</i> &bull; <i>&lt;string: new path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command renames a file.
+It is an error if there already exists a file
+with the name specified by <i>&lt;string: new path&gt;</i>.  The server may also fail rename
+requests in other situations, for example if <i>&lt;string: old path&gt;</i> and <i>&lt;string: new path&gt;</i>
+point to different file systems on the server.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdReadLink'>readlink</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; readlink &bull; <i>&lt;string: link path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command reads the target of a symbolic link.
+<i>&lt;string: link path&gt;</i> specifies the path name of the symbolic link to be read.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;string: path&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdSymLink'>symlink</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; symlink &bull; <i>&lt;string: link path&gt;</i> &bull; <i>&lt;string: target path&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command creates a symbolic link on the server.
+<i>&lt;string: link path&gt;</i> specifies the path name of the symbolic link to be created.
+<i>&lt;string: target path&gt;</i> specifies the target of the symbolic link.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdCopy'>copy</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; copy &bull; <i>&lt;string: source path&gt;</i> &bull; <i>&lt;string: destination path&gt;</i> &bull;
+    <i>&lt;boolean: copy permissions&gt;</i> &bull; <i>&lt;boolean: copy ownership&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command copies a file on remote system.
+<i>&lt;string: source path&gt;</i> specifies the path name of the file to be copied.
+<i>&lt;string: destination path&gt;</i> specifies destination file name.
+If <i>&lt;boolean: copy permissions&gt;</i> is true then copy source file permissions.
+If <i>&lt;boolean: copy ownership&gt;</i> is true then copy source file UID and GID.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdUser'>user</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; FileSystem &bull; user &bull;
+</font></b></pre>
+
+<p>The command retrieves information about user account, which is used by server 
+to access file system on behalf of the client.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;int: real UID&gt;</i> &bull; <i>&lt;int: effective UID&gt;</i> &bull;
+    <i>&lt;int: real GID&gt;</i> &bull; <i>&lt;int: effective GID&gt;</i> &bull; <i>&lt;string: home directory&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#3F5FBF>/**
+ * File System service provides file transfer (and more generally file
+ * system access) functionality in TCF. The service design is
+ * derived from SSH File Transfer Protocol specifications.
+ */</font>
+<font color=#7F0055>public interface</font> IFileSystem <font color=#7F0055>extends</font> IService {
+    
+    <font color=#3F5FBF>/**
+     * Service name.
+     */</font>
+    <font color=#7F0055>static final</font> String NAME = "FileSystem";
+
+    <font color=#3F5FBF>/**
+     * Flags to be used with open() method.
+     */</font>
+    <font color=#7F0055>static final int</font>
+    
+        <font color=#3F5FBF>/**
+         * Open the file for reading.
+         */</font>
+        TCF_O_READ              = 0x00000001,
+
+        <font color=#3F5FBF>/**
+         * Open the file for writing. If both this and TCF_O_READ are
+         * specified, the file is opened for both reading and writing.
+         */</font>
+        TCF_O_WRITE             = 0x00000002,
+
+        <font color=#3F5FBF>/**
+         * Force all writes to append data at the end of the file.
+         */</font>
+        TCF_O_APPEND            = 0x00000004, 
+
+        <font color=#3F5FBF>/**
+         * If this flag is specified, then a new file will be created if one
+         * does not already exist (if TCF_O_TRUNC is specified, the new file will
+         * be truncated to zero length if it previously exists).
+         */</font>
+        TCF_O_CREAT             = 0x00000008,
+
+        <font color=#3F5FBF>/**
+         * Forces an existing file with the same name to be truncated to zero
+         * length when creating a file by specifying TCF_O_CREAT.
+         * TCF_O_CREAT MUST also be specified if this flag is used.
+         */</font>
+        TCF_O_TRUNC             = 0x00000010,
+
+        <font color=#3F5FBF>/**
+         * Causes the request to fail if the named file already exists.
+         * TCF_O_CREAT MUST also be specified if this flag is used.
+         */</font>
+        TCF_O_EXCL              = 0x00000020;
+
+    <font color=#3F5FBF>/**
+     * Flags to be used together with FileAttrs.
+     * The flags specify which of the fields are present.  Those fields
+     * for which the corresponding flag is not set are not present (not
+     * included in the message).
+     */</font>
+    <font color=#7F0055>static final int</font>
+        ATTR_SIZE               = 0x00000001,
+        ATTR_UIDGID             = 0x00000002,
+        ATTR_PERMISSIONS        = 0x00000004,
+        ATTR_ACMODTIME          = 0x00000008;
+
+    <font color=#3F5FBF>/**
+     * FileAttrs is used both when returning file attributes from
+     * the server and when sending file attributes to the server.  When
+     * sending it to the server, the flags field specifies which attributes
+     * are included, and the server will use default values for the
+     * remaining attributes (or will not modify the values of remaining
+     * attributes).  When receiving attributes from the server, the flags
+     * specify which attributes are included in the returned data.  The
+     * server normally returns all attributes it knows about.
+     */</font>
+    <font color=#7F0055>final static class</font> FileAttrs {
+        
+        <font color=#3F5FBF>/**
+         * The `flags' specify which of the fields are present.
+         */</font>
+        <font color=#7F0055>public final int</font> flags;
+        
+        <font color=#3F5FBF>/**
+         * The `size' field specifies the size of the file in bytes.
+         */</font>
+        <font color=#7F0055>public final long</font> size;
+        
+        <font color=#3F5FBF>/**
+         * The `uid' and `gid' fields contain numeric Unix-like user and group
+         * identifiers, respectively.
+         */</font>
+        <font color=#7F0055>public final int</font> uid;
+        <font color=#7F0055>public final int</font> gid;
+        
+        <font color=#3F5FBF>/**
+         * The `permissions' field contains a bit mask of file permissions as
+         * defined by posix [1].
+         */</font>
+        <font color=#7F0055>public final int</font> permissions;
+        
+        <font color=#3F5FBF>/**
+         * The `atime' and `mtime' contain the access and modification times of
+         * the files, respectively. They are represented as milliseconds from
+         * midnight Jan 1, 1970 in UTC.
+         */</font>
+        <font color=#7F0055>public final long</font> atime;
+        <font color=#7F0055>public final long</font> mtime;
+
+        <font color=#3F5FBF>/**
+         * Additional (non-standard) attributes.
+         */</font>
+        <font color=#7F0055>public final</font> Map&lt;String,Object&gt; attributes;
+        
+        <font color=#7F0055>public</font> FileAttrs(<font color=#7F0055>int</font> flags, <font color=#7F0055>long</font> size, <font color=#7F0055>int</font> uid, <font color=#7F0055>int</font> gid,
+                <font color=#7F0055>int</font> permissions, <font color=#7F0055>long</font> atime, <font color=#7F0055>long</font> mtime, Map&lt;String,Object&gt; attributes);
+        
+        <font color=#3F5FBF>/**
+         * Determines if the file system object is a file on the remote file system.
+         * 
+         * @return true if and only if the object on the remote system can be considered to have "contents" that
+         * have the potential to be read and written as a byte stream.
+         */</font>
+        <font color=#7F0055>public boolean</font> isFile();
+
+        <font color=#3F5FBF>/**
+         * Determines if the file system object is a directory on the remote file system.
+         * 
+         * @return true if and only if the object on the remote system is a directory.
+         * That is, it contains entries that can be interpreted as other files.
+         */</font>
+        <font color=#7F0055>public boolean</font> isDirectory();
+    }
+    
+    <font color=#3F5FBF>/**
+     * The following flags are defined for the 'permissions' field:
+     */</font>
+    <font color=#7F0055>static final int</font>
+        S_IFMT     = 0170000,   // bitmask for the file type bitfields
+        S_IFSOCK   = 0140000,   // socket
+        S_IFLNK    = 0120000,   // symbolic link
+        S_IFREG    = 0100000,   // regular file
+        S_IFBLK    = 0060000,   // block device
+        S_IFDIR    = 0040000,   // directory
+        S_IFCHR    = 0020000,   // character device
+        S_IFIFO    = 0010000,   // fifo
+        S_ISUID    = 0004000,   // set UID bit
+        S_ISGID    = 0002000,   // set GID bit (see below)
+        S_ISVTX    = 0001000,   // sticky bit (see below)
+        S_IRWXU    = 00700,     // mask for file owner permissions
+        S_IRUSR    = 00400,     // owner has read permission
+        S_IWUSR    = 00200,     // owner has write permission
+        S_IXUSR    = 00100,     // owner has execute permission
+        S_IRWXG    = 00070,     // mask for group permissions
+        S_IRGRP    = 00040,     // group has read permission
+        S_IWGRP    = 00020,     // group has write permission
+        S_IXGRP    = 00010,     // group has execute permission
+        S_IRWXO    = 00007,     // mask for permissions for others (not in group)
+        S_IROTH    = 00004,     // others have read permission
+        S_IWOTH    = 00002,     // others have write permisson
+        S_IXOTH    = 00001;     // others have execute permission
+    
+    <font color=#7F0055>final static class</font> DirEntry {
+        <font color=#3F5FBF>/**
+         * `filename' is a file name being returned. It is a relative name within
+         * the directory, without any path components;
+         */</font>
+        <font color=#7F0055>public final</font> String filename;
+        
+        <font color=#3F5FBF>/**
+         * `longname' is an expanded format for the file name, similar to what
+         * is returned by "ls -l" on Unix systems.
+         * The format of the `longname' field is unspecified by this protocol.
+         * It MUST be suitable for use in the output of a directory listing
+         * command (in fact, the recommended operation for a directory listing
+         * command is to simply display this data).  However, clients SHOULD NOT
+         * attempt to parse the longname field for file attributes; they SHOULD
+         * use the attrs field instead.
+         */</font>
+        <font color=#7F0055>public final</font> String longname;
+        
+        <font color=#3F5FBF>/**
+         * `attrs' is the attributes of the file.
+         */</font>
+        <font color=#7F0055>public final</font> FileAttrs attrs;
+        
+        <font color=#7F0055>public</font> DirEntry(String filename, String longname, FileAttrs attrs);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Opaque representation of open file handle.
+     * Note: open file handle can be used only with service instance that 
+     * created the handle.
+     */</font>
+    <font color=#7F0055>interface</font> IFileHandle {
+        IFileSystem getService();
+    }
+    
+    <font color=#3F5FBF>/**
+     * Service specific error codes.
+     */</font>
+    <font color=#7F0055>static final int</font>
+    
+        <font color=#3F5FBF>/**
+         * Indicates end-of-file condition; for read() it means that no
+         * more data is available in the file, and for readdir() it
+         * indicates that no more files are contained in the directory.
+         */</font>
+        STATUS_EOF = 0x10001,
+
+        <font color=#3F5FBF>/**
+         * This code is returned when a reference is made to a file which
+         * should exist but doesn't.
+         */</font>
+        STATUS_NO_SUCH_FILE = 0x10002,
+
+        <font color=#3F5FBF>/**
+         * is returned when the authenticated user does not have sufficient
+         * permissions to perform the operation.
+         */</font>
+        STATUS_PERMISSION_DENIED = 0x10003;
+
+    
+    <font color=#3F5FBF>/**
+     * The class to represent File System error reports. 
+     */</font>
+    <font color=#7F0055>abstract static class</font> FileSystemException extends IOException {
+        
+        <font color=#7F0055>protected</font> FileSystemException(String message);
+        
+        <font color=#7F0055>protected</font> FileSystemException(Exception x)
+        
+        <font color=#3F5FBF>/**
+         * Get error code. The code can be standard TCF error code or
+         * one of service specific codes, see STATUS_*. 
+         * @return error code.
+         */</font>
+        <font color=#7F0055>public abstract int</font> getStatus();
+    }
+
+    <font color=#3F5FBF>/**
+     * Open or create a file on a remote system.
+     * 
+     * @param file_name specifies the file name.  See 'File Names' for more information.
+     * @param flags is a bit mask of TCF_O_* flags.
+     * @param attrs specifies the initial attributes for the file.
+     *  Default values will be used for those attributes that are not specified.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken open(String file_name, <font color=#7F0055>int</font> flags, FileAttrs attrs, DoneOpen done);
+    
+    <font color=#7F0055>interface</font> DoneOpen {
+        <font color=#7F0055>void</font> doneOpen(IToken token, FileSystemException error, IFileHandle handle);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Close a file on a remote system.
+     * 
+     * @param handle is a handle previously returned in the response to
+     * open() or opendir().
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken close(IFileHandle handle, DoneClose done);
+    
+    <font color=#7F0055>interface</font> DoneClose {
+        <font color=#7F0055>void</font> doneClose(IToken token, FileSystemException error);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Read bytes from an open file.
+     * In response to this request, the server will read as many bytes as it
+     * can from the file (up to `len'), and return them in a byte array.
+     * If an error occurs or EOF is encountered, the server may return
+     * fewer bytes then requested. Call back method doneRead() argument 'error'
+     * will be not null in case of error, and argument 'eof' will be
+     * true in case of EOF. For normal disk files, it is guaranteed
+     * that this will read the specified number of bytes, or up to end of file
+     * or error. For e.g. device files this may return fewer bytes than requested.
+     * 
+     * @param handle is an open file handle returned by open().
+     * @param offset is the offset (in bytes) relative
+     * to the beginning of the file from where to start reading.
+     * @param len is the maximum number of bytes to read.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken read(IFileHandle handle, long offset, <font color=#7F0055>int</font> len, DoneRead done);
+    
+    <font color=#7F0055>interface</font> DoneRead {
+        <font color=#7F0055>void</font> doneRead(IToken token, FileSystemException error, byte[] data, boolean eof);
+    }
+
+    <font color=#3F5FBF>/**
+     * Write bytes into an open file.
+     * The write will extend the file if writing beyond the end of the file.
+     * It is legal to write way beyond the end of the file; the semantics
+     * are to write zeroes from the end of the file to the specified offset
+     * and then the data.
+     * 
+     * @param handle is an open file handle returned by open().
+     * @param offset is the offset (in bytes) relative
+     * to the beginning of the file from where to start writing.
+     * @param data is byte array that contains data for writing.
+     * @param data_pos if offset in 'data' of first byte to write.
+     * @param data_size is the number of bytes to write.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken write(IFileHandle handle, long offset,
+            byte[] data, <font color=#7F0055>int</font> data_pos, <font color=#7F0055>int</font> data_size, DoneWrite done);
+
+    <font color=#7F0055>interface</font> DoneWrite {
+        <font color=#7F0055>void</font> doneWrite(IToken token, FileSystemException error);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Retrieve file attributes.
+     * 
+     * @param path - specifies the file system object for which
+     * status is to be returned.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken stat(String path, DoneStat done);
+
+    <font color=#3F5FBF>/**
+     * Retrieve file attributes.
+     * Unlike 'stat()', 'lstat()' does not follow symbolic links.
+     * 
+     * @param path - specifies the file system object for which
+     * status is to be returned.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken lstat(String path, DoneStat done);
+    
+    <font color=#3F5FBF>/**
+     * Retrieve file attributes for an open file (identified by the file handle).
+     * 
+     * @param handle is a file handle returned by 'open()'.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken fstat(IFileHandle handle, DoneStat done);
+    
+    <font color=#7F0055>interface</font> DoneStat {
+        <font color=#7F0055>void</font> doneStat(IToken token, FileSystemException error, FileAttrs attrs);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Set file attributes.
+     * This request is used for operations such as changing the ownership,
+     * permissions or access times, as well as for truncating a file.
+     * An error will be returned if the specified file system object does
+     * not exist or the user does not have sufficient rights to modify the
+     * specified attributes.
+     * 
+     * @param path specifies the file system object (e.g. file or directory)
+     * whose attributes are to be modified.
+     * @param attrs specifies the modifications to be made to file attributes.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken setstat(String path, FileAttrs attrs, DoneSetStat done);
+    
+    <font color=#3F5FBF>/**
+     * Set file attributes for an open file (identified by the file handle).
+     * This request is used for operations such as changing the ownership,
+     * permissions or access times, as well as for truncating a file.
+     * 
+     * @param handle is a file handle returned by 'open()'.
+     * @param attrs specifies the modifications to be made to file attributes.
+     * @param done is call back object.
+     * @return pending command handle.
+     */</font>
+    IToken fsetstat(IFileHandle handle, FileAttrs attrs, DoneSetStat done);
+    
+    <font color=#7F0055>interface</font> DoneSetStat {
+        <font color=#7F0055>void</font> doneSetStat(IToken token, FileSystemException error);
+    }
+    
+    <font color=#3F5FBF>/**
+     * The opendir() command opens a directory for reading.
+     * Once the directory has been successfully opened, files (and
+     * directories) contained in it can be listed using readdir() requests.
+     * When the client no longer wishes to read more names from the
+     * directory, it SHOULD call close() for the handle.  The handle
+     * should be closed regardless of whether an error has occurred or not.
+
+     * @param path - name of the directory to be listed (without any trailing slash).
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken opendir(String path, DoneOpen done);
+    
+    <font color=#3F5FBF>/**
+     * The files in a directory can be listed using the opendir() and
+     * readdir() requests.  Each readdir() request returns one
+     * or more file names with full file attributes for each file.  The
+     * client should call readdir() repeatedly until it has found the
+     * file it is looking for or until the server responds with a
+     * message indicating an error or end of file. The client should then
+     * close the handle using the close() request.
+     * Note: directory entries "." and ".." are NOT included into readdir()
+     * response.
+     * @param handle - file handle created by opendir()
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken readdir(IFileHandle handle, DoneReadDir done);
+    
+    <font color=#7F0055>interface</font> DoneReadDir {
+        <font color=#7F0055>void</font> doneReadDir(IToken token, FileSystemException error, DirEntry[] entries, boolean eof);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Create a directory on the server.
+     * 
+     * @param path - specifies the directory to be created.
+     * @param attrs - new directory attributes.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken mkdir(String path, FileAttrs attrs, DoneMkDir done);
+    
+    <font color=#7F0055>interface</font> DoneMkDir {
+        <font color=#7F0055>void</font> doneMkDir(IToken token, FileSystemException error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Remove a directory.
+     * An error will be returned if no directory
+     * with the specified path exists, or if the specified directory is not
+     * empty, or if the path specified a file system object other than a
+     * directory.
+     * 
+     * @param path - specifies the directory to be removed.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken rmdir(String path, DoneRemove done);
+    
+    <font color=#7F0055>interface</font> DoneRemove {
+        <font color=#7F0055>void</font> doneRemove(IToken token, FileSystemException error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve file system roots - top level file system objects.
+     * UNIX file system can report just one root with path "/". Other types of systems
+     * can have more the one root. For example, Windows server can return multiple roots:
+     * one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
+     * the service must use forward slash as directory separator, and must start 
+     * absolute path with "/". Server should implement proper translation of
+     * protocol file names to OS native names and back. 
+     * 
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken roots(DoneRoots done);
+    
+    <font color=#7F0055>interface</font> DoneRoots {
+        <font color=#7F0055>void</font> doneRoots(IToken token, FileSystemException error, DirEntry[] entries);
+    }
+
+    <font color=#3F5FBF>/**
+     * Remove a file or symbolic link.
+     * This request cannot be used to remove directories.
+     * 
+     * @param file_name is the name of the file to be removed.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken remove(String file_name, DoneRemove done);
+    
+    <font color=#3F5FBF>/**
+     * Canonicalize any given path name to an absolute path.
+     * This is useful for converting path names containing ".." components or
+     * relative pathnames without a leading slash into absolute paths.
+     * 
+     * @param path specifies the path name to be canonicalized.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken realpath(String path, DoneRealPath done);
+    
+    <font color=#7F0055>interface</font> DoneRealPath {
+        <font color=#7F0055>void</font> doneRealPath(IToken token, FileSystemException error, String path);
+    }
+
+    <font color=#3F5FBF>/**
+     * Rename a file.
+     * It is an error if there already exists a file
+     * with the name specified by 'new_path'.  The server may also fail rename
+     * requests in other situations, for example if `old_path' and `new_path'
+     * point to different file systems on the server.
+     * 
+     * @param old_path is the name of an existing file or directory.
+     * @param new_path is the new name for the file or directory.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken rename(String old_path, String new_path, DoneRename done);
+    
+    <font color=#7F0055>interface</font> DoneRename {
+        <font color=#7F0055>void</font> doneRename(IToken token, FileSystemException error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Read the target of a symbolic link.
+     * 
+     * @param path specifies the path name of the symbolic link to be read.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken readlink(String path, DoneReadLink done);
+    
+    <font color=#7F0055>interface</font> DoneReadLink {
+        <font color=#7F0055>void</font> doneReadLink(IToken token, FileSystemException error, String path);
+    }
+
+    <font color=#3F5FBF>/**
+     * Create a symbolic link on the server.
+     * 
+     * @param link_path specifies the path name of the symbolic link to be created.
+     * @param target_path specifies the target of the symbolic link.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken symlink(String link_path, String target_path, DoneSymLink done);
+    
+    <font color=#7F0055>interface</font> DoneSymLink {
+        <font color=#7F0055>void</font> doneSymLink(IToken token, FileSystemException error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Copy a file on remote system.
+     * 
+     * @param src_path specifies the path name of the file to be copied.
+     * @param dst_path specifies destination file name.
+     * @param copy_permissions - if true then copy source file permissions.
+     * @param copy_ownership - if true then copy source file UID and GID.
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken copy(String src_path, String dst_path,
+            boolean copy_permissions, boolean copy_ownership, DoneCopy done);
+    
+    <font color=#7F0055>interface</font> DoneCopy {
+        <font color=#7F0055>void</font> doneCopy(IToken token, FileSystemException error);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Retrieve information about user account, which is used by server 
+     * to access file system on behalf of the client.
+     *   
+     * @param done - result call back object.
+     * @return pending command handle.
+     */</font>
+    IToken user(DoneUser done);
+    
+    <font color=#7F0055>interface</font> DoneUser {
+        <font color=#7F0055>void</font> doneUser(IToken token, FileSystemException error,
+                <font color=#7F0055>int</font> real_uid, <font color=#7F0055>int</font> effective_uid, <font color=#7F0055>int</font> real_gid, <font color=#7F0055>int</font> effective_gid,
+                String home);
+    }
+}
+</pre>
+
+</body>
+</html>
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Memory.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,627 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Memory</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Memory</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+        <li><a href='#CmdSetMemory'>Set Memory</a>
+        <li><a href='#CmdGetMemory'>Get Memory</a>
+        <li><a href='#CmdFillMemory'>Fill Memory</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Memory Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+    <tr>
+        <td>1.1
+        <td>2009-03-16
+        <td>Added context properties
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>The service provides basic operations to read/write memory on a target. Command
+and event parameters are encoded as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<p>A single memory access can succeed for some addresses and fail for others. In such
+situation result message can contain partially valid data. Array of error addresses,
+in addition to error report, describes data validity on per byte basis:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;array of error addresses&gt;</i>
+    &rArr; null
+    &rArr; [ <i>&lt;error address list&gt;</i> ]
+  
+<i>&lt;error address list&gt;</i>
+    &rArr; <i>&lt;error address&gt;</i>
+    &rArr; <i>&lt;error address list&gt;</i> , <i>&lt;error address&gt;</i>
+  
+<i>&lt;error address&gt;</i>
+    &rArr; { "addr" : <i>&lt;int: range starting address&gt;</i> , "size" : <i>&lt;int: range length in bytes&gt;</i> , "stat" : <i>&lt;int: status code&gt;</i> , "msg" : <i>&lt;object: error description&gt;</i> }
+</font></b></pre>
+
+<p>If there is no entry in error addresses array for a data byte, then status of such
+byte is defined by main error report.</p>
+
+<p>Status code is bitwise or of status flags:</p>
+<dl>
+    <dt><code><b>BYTE_VALID        = 0x00</b></code> <dd>no error for this byte
+    <dt><code><b>BYTE_UNKNOWN      = 0x01</b></code> <dd>status is unknown
+    <dt><code><b>BYTE_INVALID      = 0x02</b></code> <dd>byte value in invalid, error message describes the problem
+    <dt><code><b>BYTE_CANNOT_READ  = 0x04</b></code> <dd>cannot read the byte
+    <dt><code><b>BYTE_CANNOT_WRITE = 0x08</b></code> <dd>cannot write the byte
+</dl>
+
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Memory &bull; getContext &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves context info for given context ID. A context corresponds to an
+execution thread, process, address space, etc. Exact
+meaning of a context depends on the target. Target agent should define contexts hierarchy
+that is:</p>
+ 
+<ul type='disc'>
+    <li>Sufficient to resolve possible ambiguity of a memory address;
+ 
+    <li>Adequately reflects target memory management strategy;
+ 
+    <li>Intuitive to a user.
+</ul>
+ 
+<p>For traditional OS, like UNIX, memory access context can be one of:</p>
+ 
+<ul type='disc'>
+    <li>Kernel address space;
+ 
+    <li>A process.
+</ul>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Context data object should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;.</i></font></b>
+Context data is expected to be cached by clients.
+Service sends contextChanged event to notify changes in context data.</p>
+
+<p>Predefined memory context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of a parent context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ProcessID" : <i>&lt;string&gt;</i></font></b></code>
+    - process ID.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"BigEndian" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if memory is big-endian.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"AddressSize" : <i>&lt;int&gt;</i></font></b></code>
+    - size of memory address in bytes.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;int&gt;</i></font></b></code>
+    - name of the context, can be used for UI purposes.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StartBound" : <i>&lt;int&gt;</i></font></b></code>
+    - lowest address (inclusive) which is valid for the context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"EndBound" : <i>&lt;int&gt;</i></font></b></code>
+    - highest address (inclusive) which is valid for the context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"AccessTypes" : <i>&lt;array of strings&gt;</i></font></b></code>
+    - Defines the access types allowed for this context.
+        <p>Target system can support multiple different memory access types, like instruction and data access.
+    Different access types can use different logic for address translation and memory mapping, so they can
+    end up accessing different data bits, even if address is the same.
+    Each distinct access type should be represented by separate memory context.
+    A memory context can represent multiple access types if they are equivalent - all access same memory bits.
+    Same data bits can be exposed through multiple memory contexts.</p>
+
+    <p>Predefined access types are:</p>
+    <ul>
+        <li><code><b><font face="Courier New" size=2 color=#333399>"instruction"</font></b></code>
+        - Context represent instructions fetch access.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"data"</font></b></code>
+        - Context represents data access.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"io"</font></b></code>
+        - Context represents IO peripherals.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"user"</font></b></code>
+        - Context represents a user (e.g. application running in Linux) view to memory.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"supervisor"</font></b></code>
+        - Context represents a supervisor (e.g. Linux kernel) view to memory.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"hypervisor"</font></b></code>
+        - Context represents a hypervisor view to memory.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"virtual"</font></b></code>
+        - Context uses virtual addresses.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"physical"</font></b></code>
+        - Context uses physical addresses.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"cache"</font></b></code>
+        - Context is a cache.
+
+        <li><code><b><font face="Courier New" size=2 color=#333399>"tlb"</font></b></code>
+        - Context is a TLB memory.
+    </ul>
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Memory &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of contexts available for memory access commands.</p>
+ 
+<p>Parent context ID can be null &ndash; to retrieve top level of the hierarchy, can be one
+of context IDs retrieved by previous getChildren commands, or it can be obtained from another service.
+Contexts hierarchy can be simple plain list or it can form a tree. It is up to target agent developers to
+choose layout that is most descriptive for a given target.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;<i></i>
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+
+</font></b></pre>
+
+<h3><a name='CmdSetMemory'>Set Memory</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Memory &bull; set &bull; 
+    <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: address&gt;</i> &bull; <i>&lt;int: word size&gt;</i> &bull;
+    <i>&lt;int: byte count&gt;</i> &bull; <i>&lt;int: mode&gt;</i> &bull; <i>&lt;string: BASE64 encoded byte array&gt;</i> &bull;
+</font></b></pre>
+
+<p>Writes data bytes at given address in memory, "word size" bytes at a time. Address
+should be aligned by "word size". Context ID must be one returned by getContexts.
+Mode is logical OR of any combination of:</p>
+ 
+<ul type='disc'>
+    <li>0x1 &ndash; continue on error (like bus error or page fault)
+ 
+    <li>0x2 &ndash; verify data after writing by reading back and compare
+</ul>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of error addresses&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error. Error addresses, when present, let client know which bytes of data failed
+to be written into memory.</p>
+
+<h3><a name='CmdGetMemory'>Get Memory</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Memory &bull; get &bull;
+    <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: address&gt;</i> &bull; <i>&lt;int: word size&gt;</i> &bull;
+    <i>&lt;int: byte count&gt;</i> &bull; <i>&lt;int: mode&gt;</i> &bull;
+</font></b></pre>
+
+<p>Reads data bytes at given address in memory, "word size" bytes at a time. Address
+should be aligned by "word size". Context ID must be one returned by getContexts.
+Mode is logical OR of any combination of:</p>
+ 
+<ul type='disc'>
+    <li>0x1 &ndash; continue on error (like bus error or page fault)
+ 
+    <li>0x2 &ndash; verify data after reading by re-reading and compare
+</ul>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;string: BASE64 encoded byte array&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of error addresses&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error. Error addresses, when present, let client know which bytes of data failed
+to be retrieved from memory.</p>
+
+<h3><a name='CmdFillMemory'>Fill Memory</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Memory &bull; fill &bull; 
+    <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: address&gt;</i> &bull; <i>&lt;int: word size&gt;</i> &bull;
+    &lt;int: byte count&gt; &bull; <i>&lt;int: mode&gt;</i> &bull; <i>&lt;array: array of pattern bytes&gt;</i> &bull;
+</font></b></pre>
+
+<p>Writes pattern bytes at given address in memory, "word size" bytes at a time. Address
+should be aligned by "word size". If "byte count" is bigger then pattern size, then
+pattern is repeated necessary number of times. Context ID must be one returned by
+getContexts. Mode is logical OR of any combination of:</p>
+ 
+<ul type='disc'>
+    <li>0x1 &ndash; continue on error (like bus error or page fault)
+ 
+    <li>0x2 &ndash; verify data after writing by reading back and compare
+</ul>
+  
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of error addresses&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error. Error addresses, when present, let client know which bytes of data failed
+to be written into memory.</p>
+
+<h2><a name='Events'>Events</a></h2>
+ 
+<p>Memory service broadcasts notification events when memory contexts are added, removed
+or changed, and when memory content is altered by "set" or "fill" commands.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Memory &bull; contextAdded &bull; <i>&lt;array of context data&gt;</i> &bull;
+E &bull; Memory &bull; contextChanged &bull; <i>&lt;array of context data&gt;</i> &bull;
+E &bull; Memory &bull; contextRemoved &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+E &bull; Memory &bull; memoryChanged &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;array of address ranges&gt;</i> &bull;
+  
+<i>&lt;array of context data&gt;</i> <font face="Times New Roman" size=3>- see Get Contexts command.</font>
+  
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+  
+<i>&lt;array of address ranges&gt;</i>
+    &rArr; null
+    &rArr; [ <i>&lt;address ranges list&gt;</i> ]
+  
+<i>&lt;address ranges list&gt;</i>
+    &rArr; <i>&lt;address range&gt;</i>
+    &rArr; <i>&lt;address ranges list&gt;</i> , <i>&lt;address range&gt;</i>
+
+<i>&lt;address range&gt;</i>
+    &rArr; { "addr" : <i>&lt;int: range starting address&gt;</i> , "size" : <i>&lt;int: range length in bytes&gt;</i> }
+</font></b></pre>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#3F5FBF>/**
+ * IMemory service provides basic operations to read/write memory on a target.
+ */</font>
+<font color=#7F0055>public interface</font> Memory <font color=#7F0055>extends</font> Service {
+  
+    <font color=#7F0055>static final</font> String NAME = "Memory";
+
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        PROP_ID = "ID",                         <font color=#3F5FBF>/** String, ID of the context, same as getContext command argument */</font>
+        PROP_PARENT_ID = "ParentID",            <font color=#3F5FBF>/** String, ID of a parent context */</font>
+        PROP_PROCESS_ID = "ProcessID",          <font color=#3F5FBF>/** String, process ID, see Processes service */</font>
+        PROP_BIG_ENDIAN = "BigEndian",          <font color=#3F5FBF>/** Boolean, true if memory is big-endian */</font>
+        PROP_ADDRESS_SIZE = "AddressSize",      <font color=#3F5FBF>/** Number, size of memory address in bytes */</font>
+        PROP_NAME = "Name",                     <font color=#3F5FBF>/** String, name of the context, can be used for UI purposes */</font>
+        PROP_START_BOUND = "StartBound",        <font color=#3F5FBF>/** Number, lowest address (inclusive) which is valid for the context */</font>
+        PROP_END_BOUND = "EndBound",            <font color=#3F5FBF>/** Number, highest address (inclusive) which is valid for the context */</font>
+        PROP_ACCESS_TYPES = "AccessTypes";      <font color=#3F5FBF>/** Array of String, the access types allowed for this context */</font>
+    
+    <font color=#3F5FBF>/**
+     * Values of "AccessTypes".
+     * Target system can support multiple different memory access types, like instruction and data access.
+     * Different access types can use different logic for address translation and memory mapping, so they can
+     * end up accessing different data bits, even if address is the same.
+     * Each distinct access type should be represented by separate memory context.
+     * A memory context can represent multiple access types if they are equivalent - all access same memory bits.
+     * Same data bits can be exposed through multiple memory contexts.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        ACCESS_INSTRUCTION = "instruction",     <font color=#3F5FBF>/** Context represent instructions fetch access */</font>
+        ACCESS_DATA = "data",                   <font color=#3F5FBF>/** Context represents data access */</font>
+        ACCESS_IO = "io",                       <font color=#3F5FBF>/** Context represents IO peripherals */</font>
+        ACCESS_USER = "user",                   <font color=#3F5FBF>/** Context represents a user (e.g. application running in Linux) view to memory */</font>
+        ACCESS_SUPERVISOR = "supervisor",       <font color=#3F5FBF>/** Context represents a supervisor (e.g. Linux kernel) view to memory */</font>
+        ACCESS_HYPERVISOR = "hypervisor",       <font color=#3F5FBF>/** Context represents a hypervisor view to memory */</font>
+        ACCESS_VIRTUAL = "virtual",             <font color=#3F5FBF>/** Context uses virtual addresses */</font>
+        ACCESS_PHYSICAL = "physical",           <font color=#3F5FBF>/** Context uses physical addresses */</font>
+        ACCESS_CACHE = "cache",                 <font color=#3F5FBF>/** Context is a cache */</font>
+        ACCESS_TLB = "tlb";                     <font color=#3F5FBF>/** Context is a TLB memory */</font>
+    
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context ID.
+     *   
+     * <font color=#7F9FBF>@param</font> id &ndash; context ID. 
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getContext(String id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client callback interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; context data.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, MemoryContext context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve contexts available for memory commands.
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service.
+     *  
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID. Can be null &ndash;
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContexts commands.
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    <font color=#3F5FBF>/**
+     * Client callback interface for getChildren().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> contexts &ndash; array of available context IDs.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+
+    <font color=#3F5FBF>/**
+     * Memory access mode:
+     * Carry on when some of the memory cannot be accessed and
+     * return MemoryError at the end if any of the bytes
+     * were not processed correctly.
+     */</font>
+    <font color=#7F0055>final static int</font> MODE_CONTINUEONERROR = 0x1;
+ 
+    <font color=#3F5FBF>/**
+     * Memory access mode:
+     * Verify result of memory operations (by reading and comparing).
+     */</font>
+    <font color=#7F0055>final static int</font> MODE_VERIFY = 0x2;
+ 
+    <font color=#7F0055>interface</font> MemoryContext {
+ 
+        <font color=#3F5FBF>/** 
+         * Get context ID.
+         * <font color=#7F9FBF>@return</font> context ID.
+         */</font>
+        String getID();
+
+        <font color=#3F5FBF>/** 
+         * Get parent context ID.
+         * <font color=#7F9FBF>@return</font> parent ID.
+         */</font>
+        String getParentID();
+        
+        <font color=#3F5FBF>/** 
+         * Get process ID, if applicable.
+         * <font color=#7F9FBF>@return</font> process ID.
+         */</font>
+        String getProcessID();
+        
+        <font color=#3F5FBF>/** 
+         * Get memory endianess.
+         * <font color=#7F9FBF>@return</font> true if memory id big-endian.
+         */</font>
+        boolean isBigEndian();
+        
+        <font color=#3F5FBF>/** 
+         * Get memory address size.
+         * <font color=#7F9FBF>@return</font> number of bytes used to store memory address value.
+         */</font>
+        <font color=#7F0055>int</font> getAddressSize();
+        
+        <font color=#3F5FBF>/** 
+         * Get memory context name.
+         * The name can be used for UI purposes.
+         * <font color=#7F9FBF>@return</font> context name.
+         */</font>
+        String getName();
+        
+        <font color=#3F5FBF>/** 
+         * Get lowest address (inclusive) which is valid for the context.
+         * <font color=#7F9FBF>@return</font> lowest address.
+         */</font>
+        Number getStartBound();
+        
+        <font color=#3F5FBF>/** 
+         * Get highest address (inclusive) which is valid for the context.
+         * <font color=#7F9FBF>@return</font> highest address.
+         */</font>
+        Number getEndBound();
+        
+        <font color=#3F5FBF>/** 
+         * Get the access types allowed for this context.
+         * <font color=#7F9FBF>@return</font> collection of access type names.
+         */</font>
+        Collection&lt;String> getAccessTypes();
+
+        <font color=#3F5FBF>/** 
+         * Get context properties.
+         * <font color=#7F9FBF>@return</font> all available context properties.
+         */</font>
+        Map&lt;String,Object> getProperties();
+ 
+        <font color=#3F5FBF>/**
+         * Set target memory.
+         * If 'word_size' is 0 it means client does not care about word size.
+         */</font>
+        <font color=#7F0055>void</font> set(long addr, <font color=#7F0055>int</font> word_size, byte[] buf,
+                         <font color=#7F0055>int</font> offs, <font color=#7F0055>int</font> size, <font color=#7F0055>int</font> mode, DoneMemory done);
+ 
+        <font color=#3F5FBF>/**
+         * Read target memory.
+         */</font>
+        <font color=#7F0055>void</font> get(long addr, <font color=#7F0055>int</font> word_size, byte[] buf,
+                         <font color=#7F0055>int</font> offs, <font color=#7F0055>int</font> size, <font color=#7F0055>int</font> mode, DoneMemory done);
+ 
+        <font color=#3F5FBF>/**
+         * Fill target memory with given pattern.
+         * 'size' is number of bytes to fill.
+         */</font>
+        <font color=#7F0055>void</font> fill(long addr, <font color=#7F0055>int</font> word_size, byte[] value,
+                          <font color=#7F0055>int</font> size, <font color=#7F0055>int</font> mode, DoneMemory done);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Client callback interface for set(), get() and fill().
+     */</font>
+    <font color=#7F0055>interface</font> DoneMemory {
+        <font color=#7F0055>void</font> doneMemory(MemoryError error);
+    }
+
+    <font color=#7F0055>class</font> MemoryError <font color=#7F0055>extends</font> Exception {
+    }
+  
+    <font color=#3F5FBF>/**
+     * ErrorOffset interface can be implemented by MemoryError object,
+     * which is returned by get, set and fill commands.
+     *
+     * get/set/fill () returns this exception when reading failed
+     * for some but not all bytes, and MODE_CONTINUEONERROR
+     * has been set in mode. (For example, when only part of the request
+     * translates to valid memory addresses.)
+     * Exception.getMessage can be used for generalized message of the
+     * possible reasons of partial memory operation.
+     */</font>
+    <font color=#7F0055>interface</font> ErrorOffset {
+        
+        // Error may have per byte information
+        <font color=#7F0055>final static int</font> 
+            BYTE_VALID        = 0x00,
+            BYTE_UNKNOWN      = 0x01, // e.g. out of range
+            BYTE_INVALID      = 0x02,
+            BYTE_CANNOT_READ  = 0x04,
+            BYTE_CANNOT_WRITE = 0x08;
+ 
+        <font color=#7F0055>int</font> getStatus(<font color=#7F0055>int</font> offset);
+ 
+        <font color=#3F5FBF>/**
+         * Returns the detail message string about the
+         * byte associated with specified location.
+         * <font color=#7F9FBF>@return</font>  the detail error message string.
+         */</font>
+        String getMessage(<font color=#7F0055>int</font> offset);
+        
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Add memory service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> addListener(MemoryListener listener);
+
+    <font color=#3F5FBF>/**
+     * Remove memory service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(MemoryListener listener);
+
+    <font color=#3F5FBF>/**
+     * Memory event listener is notified when memory context hierarchy
+     * changes, and when memory is modified by memory service commands. 
+     */</font>
+    <font color=#7F0055>interface</font> MemoryListener {
+ 
+        <font color=#3F5FBF>/**
+         * Called when a new memory access context(s) is created.
+         */</font>
+        <font color=#7F0055>void</font> contextAdded(Context[] contexts);
+ 
+        <font color=#3F5FBF>/**
+         * Called when a new memory access context(s) properties changed.
+         */</font>
+        <font color=#7F0055>void</font> contextChanged(Context[] contexts);
+ 
+        <font color=#3F5FBF>/**
+         * Called when memory access context(s) is removed.
+         */</font>
+        <font color=#7F0055>void</font> contextRemoved(String[] context_ids);
+ 
+        <font color=#3F5FBF>/**
+         * Called when target memory content was changed and clients 
+         * need to update themselves. Clients, at least, should invalidate
+         * corresponding cached memory data.
+         * Not every change is notified - it is not possible,
+         * only those, which are not caused by normal execution of the debuggee.
+         * &lsquo;addr&rsquo; and &lsquo;size&rsquo; can be null if unknown.
+         */</font>
+        <font color=#7F0055>void</font> memoryChanged(String context_id,
+               long[] addr, long[] size);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Processes.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,642 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Processes</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Processes</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+        <li><a href='#CmdAttach'>Attach</a>
+        <li><a href='#CmdDetach'>Detach</a>
+        <li><a href='#CmdTerminate'>Terminate</a>
+        <li><a href='#CmdGetSignalList'>Get Signal List</a>
+        <li><a href='#CmdGetSignalMask'>Get Signal Mask</a>
+        <li><a href='#CmdSetSignalMask'>Set Signal Mask</a>
+        <li><a href='#CmdSignal'>Signal</a>
+        <li><a href='#CmdGetEnvironment'>Get Environment</a>
+        <li><a href='#CmdStart'>Start</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Processes Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>0.2
+        <td>2009-02-26
+        <td>Added signal and environment commands, and properties for standard I/O redirection 
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>Processes service provides access to the target OS's process 
+information, allows to start and terminate a process, and allows
+to attach and detach a process for debugging. Debug services,
+like Memory and Run Control, require a process to be attached
+before they can access it.</p>
+
+<p>If a process is started by this service, its standard input/output streams are 
+available for client to read/write using <a href='TCF Service - Streams.html'>Streams Service</a>. Stream type of such
+streams is set to "Processes".</p>
+
+<p>Command and event parameters are encoded
+as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; getContext &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves context info for given context ID.
+A context corresponds to an execution thread, process, address space, etc.
+Context IDs are valid across TCF services, so it is allowed to issue 'Processes.getContext'
+command with a context that was obtained, for example, from Memory service.
+However, 'Processes.getContext' is supposed to return only process specific data.
+If the ID is not a process ID, 'Processes.getContext' may not return any
+useful information.
+</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Context data object should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;.</i></font></b>
+</p>
+
+<p>Predefined process context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - parent context ID.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - process name. Client UI can show this name to a user.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Attached" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the context is attached to debugger.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CanTerminate" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the service can terminate the process.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StdInID" : <i>&lt;string&gt;</i></font></b></code>
+    - process standard input stream ID.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StdOutID" : <i>&lt;string&gt;</i></font></b></code>
+    - process standard output stream ID.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StdErrID" : <i>&lt;string&gt;</i></font></b></code>
+    - process standard error stream ID.
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull; <i>&lt;boolean: attached only&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of contexts available for process control commands.</p>
+ 
+<p>Parent context ID can be null &ndash; to retrieve top level of the hierarchy, can be one
+of context IDs retrieved by previous getChildren commands, or it can be obtained from another service.
+Contexts hierarchy can be simple plain list or it can form a tree. It is up to target agent developers to
+choose layout that is most descriptive for a given target.</p>
+<p>If <i>&lt;boolean: attached only&gt;</i> is true, the command returns only those processes that are attached for debugging.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+</font></b></pre>
+
+<h3><a name='CmdAttach'>Attach</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; attach &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command attaches debugger to a process.
+Services like Run Control, Memory, Breakpoints work only with attached processes.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdDetach'>Detach</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; detach &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command detaches debugger from a process.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdTerminate'>Terminate</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; terminate &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command terminates a process.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetSignalList'>Get Signal List</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; getSignalList &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command returns a complete list of available signals. The list containg all signals that can be sent to a given context.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of signal descriptions&gt;</i> &bull;
+
+<i>&lt;array of signal descriptions&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;signal description list&gt;</i> ]
+  
+<i>&lt;signal description list&gt;</i>
+    &rArr; <i>&lt;object: signal description&gt;</i>
+    &rArr; <i>&lt;signal description list&gt;</i> , <i>&lt;object: signal description&gt;</i>
+</font></b></pre>
+
+<p>Signal description is a list of properties. Predefined signal properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Index" : <i>&lt;int&gt;</i></font></b></code>
+    - bit position of the signal in bitsets that are used by Get Signal Mask and Set Signal Mask commands.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - signal name. Client UI can show this name to a user.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Code" : <i>&lt;string&gt;</i></font></b></code>
+    - human readable description of the signal.
+</ul>
+
+
+<h3><a name='CmdGetSignalMask'>Get Signal Mask</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; getSignalMask &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command returns signal mask of a process or a thread.
+Bits in the mask control how signals should be handled by debug agent.
+When new context is created it inherits the mask from its parent.
+If context is not attached the command will return an error.</p>
+
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;int: don't stop bitset&gt;</i> &bull; <i>&lt;int: don't pass bitset&gt;</i> &bull; <i>&lt;int: pending bitset&gt;</i> &bull;
+</font></b></pre>
+<ul>
+    <li>don't stop bitset - signals that should suspend execution of the context.
+    <li>don't pass bitset - signals that should not be delivered to the context.
+    <li>pending bitset - signals that are generated but not delivered yet.
+</ul>
+Note: "pending bitset" is meaningful only if the context is suspended.
+
+<h3><a name='CmdSetSignalMask'>Set Signal Mask</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; setSignalMask &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: don't stop bitset&gt;</i> &bull; <i>&lt;int: don't pass bitset&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command sets signal mask of a process or a thread.
+Bits in the mask control how signals should be handled by debug agent.
+If context is not attached the command will return an error.</p>
+<ul>
+    <li>don't stop bitset - signals that should not suspend execution of the context.
+    By default, debugger suspends a process before it receives a signal.  
+    <li>don't pass bitset - signals that should not be delivered to the context.
+</ul>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdSignal'>Signal</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; signal &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: signal&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command sends a signal to a context.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetEnvironment'>Get Environment</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; getEnvironment &bull;
+</font></b></pre>
+
+<p>The command returns default set of environment variables used to start a new process.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;object: environment variables&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdStart'>Start</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Processes &bull; start &bull; <i>&lt;string: working directory&gt;</i> &bull; <i>&lt;string: program image file&gt;</i> &bull;
+    <i>&lt;string array: command line&gt;</i> &bull; <i>&lt;object: environment variables&gt;</i> &bull; <i>&lt;boolean: attach&gt;</i> &bull;
+
+<i>&lt;string array&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;string list&gt;</i> ]
+  
+<i>&lt;string list&gt;</i>
+    &rArr; <i>&lt;string&gt;</i>
+    &rArr; <i>&lt;string list&gt;</i> , <i>&lt;string&gt;</i>
+</font></b></pre>
+
+<p>The command starts a new process on remote machine.
+<ul>
+        <li><i>&lt;string: working directory&gt;</i> - initial value of working directory for the process.
+        <li><i>&lt;string: program image file&gt;</i> - image file to start process with.
+        <li><i>&lt;string array: command line&gt;</i> - command line arguments for the process.
+        <li><i>&lt;object: environment variables&gt;</i> - list of environment variables for the process,
+        they will be added to default process environment. 
+        <li><i>&lt;boolean: attach&gt;</i> - if true debugger should be attached to the process.</p>
+</ul>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+</font></b></pre>
+
+<p>On success the command returns context data for created process. Context data has same format as Get Context result.</p>
+
+<h2><a name='Events'>Events</a></h2>
+
+<p>Processes service broadcasts notification event when a proceess exits.
+Only processes that were started by the service will generate exit event.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Processes &bull; exited &bull; <i>&lt;string: process ID&gt;</i> &bull; <i>&lt;int: exit code&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#7F0055>public interface</font> IProcesses <font color=#7F0055>extends</font> IService {
+
+    <font color=#7F0055>static final</font> String NAME = "Processes";
+    
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context ID.
+     * A context corresponds to an execution thread, process, address space, etc.
+     * Context IDs are valid across TCF services, so it is allowed to issue
+     * 'IProcesses.getContext' command with a context that was obtained,
+     * for example, from Memory service.
+     * However, 'Processes.getContext' is supposed to return only process specific data,
+     * If the ID is not a process ID, 'IProcesses.getContext' may not return any
+     * useful information
+     *    
+     * <font color=#7F9FBF>@param</font> id &ndash; context ID. 
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getContext(String id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; context data.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, ProcessContext context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve children of given context.
+     *   
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID. Can be null &ndash;
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * <font color=#7F9FBF>@param</font> attached_only - if true return only attached process IDs.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, <font color=#7F0055>boolean</font> attached_only, DoneGetChildren done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getChildren().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context_ids &ndash; array of available context IDs.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        <font color=#3F5FBF>/** The TCF context ID */</font>
+        PROP_ID = "ID",
+        
+        <font color=#3F5FBF>/** The TCF parent context ID */</font>
+        PROP_PARENTID = "ParentID",
+        
+        <font color=#3F5FBF>/** Is the context attached */</font>
+        PROP_ATTACHED = "Attached",
+        
+        <font color=#3F5FBF>/** Can terminate the context */</font>
+        PROP_CAN_TERMINATE = "CanTerminate",
+        
+        <font color=#3F5FBF>/** Process name. Client UI can show this name to a user */</font>
+        PROP_NAME = "Name",
+
+        <font color=#3F5FBF>/** Process standard input stream ID */</font>
+        PROP_STDIN_ID = "StdInID",
+        
+        <font color=#3F5FBF>/** Process standard output stream ID */</font>
+        PROP_STDOUT_ID = "StdOutID",
+        
+        <font color=#3F5FBF>/** Process standard error stream ID */</font>
+        PROP_STDERR_ID = "StdErrID";
+   
+    <font color=#7F0055>interface</font> ProcessContext {
+        
+        <font color=#3F5FBF>/** 
+         * Get context ID.
+         * Same as getProperties().get(&ldquo;ID&rdquo;)
+         */</font>
+        String getID();
+
+        <font color=#3F5FBF>/**
+         * Get parent context ID.
+         * Same as getProperties().get(&ldquo;ParentID&rdquo;)
+         */</font>
+        String getParentID();
+
+        <font color=#3F5FBF>/**
+         * Get process name.
+         * Client UI can show this name to a user.
+         * Same as getProperties().get(&ldquo;Name&rdquo;)
+         */</font>
+        String getName();
+
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_ATTACHED.
+         * Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+         * <font color=#7F9FBF>@return</font> value of PROP_ATTACHED.
+         */</font>
+        <font color=#7F0055>boolean</font> isAttached();
+
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_CAN_TERMINATE.
+         * <font color=#7F9FBF>@return</font> value of PROP_CAN_TERMINATE.
+         */</font>
+        <font color=#7F0055>boolean</font> canTerminate();
+
+        <font color=#3F5FBF>/**
+         * Get all available context properties.
+         * <font color=#7F9FBF>@return</font> Map 'property name' -> 'property value'
+         */</font>
+        Map&lt;String, Object&gt; getProperties();
+        
+        <font color=#3F5FBF>/**
+         * Attach debugger to a process.
+         * Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+         * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken attach(DoneCommand done);
+
+        <font color=#3F5FBF>/**
+         * Detach debugger from a process.
+         * Process execution will continue without debugger supervision.
+         * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken detach(DoneCommand done);
+        
+        <font color=#3F5FBF>/**
+         * Terminate a process. 
+         * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken terminate(DoneCommand done);
+    }
+    
+    <font color=#7F0055>interface</font> DoneCommand {
+        <font color=#7F0055>void</font> doneCommand(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Signal property names used by "getSignalList" command.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        <font color=#3F5FBF>/** Number, bit position in the signal mask */</font>
+        SIG_INDEX = "Index",
+        
+        <font color=#3F5FBF>/** String, signal name, for example "SIGHUP" */</font>
+        SIG_NAME = "Name",
+        
+        <font color=#3F5FBF>/** Number, signal code, as defined by OS */</font>
+        SIG_CODE = "Code",
+        
+        <font color=#3F5FBF>/** String, human readable description of the signal */</font>
+        SIG_DESCRIPTION = "Description";
+    
+    <font color=#3F5FBF>/**
+     * Get list of signals that can be send to the context.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken getSignalList(String context_id, DoneGetSignalList done);
+
+    <font color=#3F5FBF>/**
+     * Call-back interface to be called when "getSignalList" command is complete.
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetSignalList {
+        <font color=#7F0055>void</font> doneGetSignalList(IToken token, Exception error, Collection<Map<String,Object>> list);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Get process or thread signal mask.
+     * Bits in the mask control how signals should be handled by debug agent.
+     * When new context is created it inherits the mask from its parent.
+     * If context is not attached the command will return an error. 
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken getSignalMask(String context_id, DoneGetSignalMask done);
+    
+    <font color=#3F5FBF>/**
+     * Call-back interface to be called when "getSignalMask" command is complete.
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetSignalMask {
+        <font color=#3F5FBF>/**
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> dont_stop - bit-set of signals that should suspend execution of the context.
+         * <font color=#7F9FBF>@param</font> dont_pass - bit-set of signals that should not be delivered to the context.
+         * <font color=#7F9FBF>@param</font> pending - bit-set of signals that are generated but not delivered yet.
+         * Note: "pending" is meaningful only if the context is suspended.
+         */</font>
+        <font color=#7F0055>void</font> doneGetSignalMask(IToken token, Exception error, <font color=#7F0055>int</font> dont_stop, <font color=#7F0055>int</font> dont_pass, <font color=#7F0055>int</font> pending);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Set process or thread signal mask. 
+     * Bits in the mask control how signals should be handled by debug agent.
+     * If context is not attached the command will return an error. 
+     * <font color=#7F9FBF>@param</font> dont_stop - bit-set of signals that should not suspend execution of the context.
+     * By default, debugger suspends a context before it receives a signal.  
+     * <font color=#7F9FBF>@param</font> dont_pass - bit-set of signals that should not be delivered to the context.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken setSignalMask(String context_id, <font color=#7F0055>int</font> dont_stop, <font color=#7F0055>int</font> dont_pass, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Send a signal to a process or thread.
+     * <font color=#7F9FBF>@param</font> context_id - context ID.
+     * <font color=#7F9FBF>@param</font> signal - signal code.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken signal(String context_id, <font color=#7F0055>long</font> signal, DoneCommand done);
+
+    <font color=#3F5FBF>/**
+     * Get default set of environment variables used to start a new process.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken getEnvironment(DoneGetEnvironment done);
+    
+    <font color=#3F5FBF>/**
+     * Call-back interface to be called when "getEnvironment" command is complete.
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetEnvironment {
+        <font color=#7F0055>void</font> doneGetEnvironment(IToken token, Exception error, Map<String,String> environment);
+    }
+
+    <font color=#3F5FBF>/**
+     * Start a new process on remote machine.
+     * <font color=#7F9FBF>@param</font> directory - initial value of working directory for the process.
+     * <font color=#7F9FBF>@param</font> file - process image file.
+     * <font color=#7F9FBF>@param</font> command_line - command line arguments for the process.
+     * <font color=#7F9FBF>@param</font> environment - list of environment variables for the process. 
+     * if null then default set of environment variables will be used. 
+     * <font color=#7F9FBF>@param</font> attach - if true debugger should be attached to the process.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+     */</font>
+    IToken start(String directory, String file,
+            String[] command_line, String[] environment, <font color=#7F0055>boolean</font> attach, DoneStart done);
+    
+    <font color=#3F5FBF>/**
+     * Call-back interface to be called when "start" command is complete.
+     */</font>
+    <font color=#7F0055>interface</font> DoneStart {
+        <font color=#7F0055>void</font> doneStart(IToken token, Exception error, ProcessContext process);
+    }
+
+    <font color=#3F5FBF>/**
+     * Add processes service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> addListener(ProcessesListener listener);
+
+    <font color=#3F5FBF>/**
+     * Remove processes service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(ProcessesListener listener);
+
+    <font color=#3F5FBF>/**
+     * Process event listener is notified when a process exits.
+     * Event are reported only for processes that were started by 'start' command. 
+     */</font>
+    <font color=#7F0055>interface</font> ProcessesListener {
+        
+        <font color=#3F5FBF>/**
+         * Called when a process exits.
+         * <font color=#7F9FBF>@param</font> process_id - process context ID
+         * <font color=#7F9FBF>@param</font> exit_code - process exit code
+         */</font>
+        <font color=#7F0055>void</font> exited(String process_id, <font color=#7F0055>int</font> exit_code);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Registers.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,832 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Registers</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Registers</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+        <li><a href='#CmdSetRegister'>Set Register</a>
+        <li><a href='#CmdGetRegister'>Get Register</a>
+        <li><a href='#CmdSetMultiple'>Set Multiple Registers</a>
+        <li><a href='#CmdGetMultiple'>Get Multiple Registers</a>
+        <li><a href='#CmdSearch'>Search for Registers</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Registers Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>0.2
+        <td>2008-04-23
+        <td>Added get/set multiple
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+    <tr>
+        <td>1.1
+        <td>2009-03-16
+        <td>Added search command and several context properties
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>The service provides basic operations to read/write CPU and hardware registers. Command
+and event parameters are encoded as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+
+In addition to commands that can set/get individual register context values, the service defines commands to set/get values at
+multiple locations. This allows:
+<ol>
+    <li> to get/set multiple register contexts in one command
+    <li> to specify offset and size for get/set on large register groups
+    <li> to get/set truncated register values, e.g. only the low 32 bits of a 64-bit register
+</ol>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Registers &bull; getContext &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves context info for given context ID. A context corresponds to an
+register, register group, register bit field, etc. Exact meaning of a context depends on the target.
+Target agent should define contexts hierarchy that is:</p>
+ 
+<ul type='disc'>
+    <li>Adequately reflects target hardware registers layout;
+    <li>Consistent with the lingo/terminology of the processor manuals;
+    <li>Intuitive to a user.
+</ul>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Context data object should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;.</i></font></b>
+Context data is expected to be cached by clients.
+Service sends contextChanged event to notify changes in context data.</p>
+
+<p>Predefined register context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of a parent context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ProcessID" : <i>&lt;string&gt;</i></font></b></code>
+    - process ID.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - context name.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Description" : <i>&lt;string&gt;</i></font></b></code>
+    - context description.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Size" : <i>&lt;int&gt;</i></font></b></code>
+    - context size in bytes. Byte arrays in get/set commands should be same size.
+    Hardware register can be smaller then this size, for example in case
+    when register size is not an even number of bytes. In such case implementation
+    should add/remove padding that consists of necessary number of zero bits.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Readable" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if context value can be read.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ReadOnce" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if reading the context (register) destroys its current value - it can be read only once.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Writeable" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if context value can be written.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"WriteOnce" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if register value can not be overwritten - every write counts.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"SideEffects" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if writing the context can change values of other registers.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Volatile" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the register value can change even when target is stopped.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Float" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the register value is a floating-point value.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"BigEndian" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if big endian, which means decreasing numeric significance with increasing bit number.
+    If absent default if false, which implies little endianess. The endianess is used to encode and decode values of get, getm, set and setm commands.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"LeftToRight" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the lowest numbered bit (i.e. bit #0 or bit #1, depending on "FirstBit" value) should be shown to user as the left-most bit.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"FirstBit" : <i>&lt;int&gt;</i></font></b></code>
+    - 0 or 1. If the context has bit field children, bit positions of the fields can be zero-based or 1-based.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Bits" : <i>&lt;array of int&gt;</i></font></b></code>
+    - if context is a bit field, contains the field bit numbers in the parent context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Values" : <i>&lt;array of named values&gt;</i></font></b></code>
+    - predefined names (mnemonics) for some of context values.
+        <pre><b><font face="Courier New" size=2 color=#333399>
+        <i>&lt;array of named values&gt;</i>
+                &rArr; null
+                &rArr; [ ]
+                &rArr; [ <i>&lt;named values list&gt;</i> ]
+  
+        <i>&lt;named values list&gt;</i>
+                &rArr; <i>&lt;object: named value properties&gt;</i>
+                &rArr; <i>&lt;named values list&gt;</i> , <i>&lt;object: named value properties&gt;</i>
+        </font></b></pre>
+    Named value properties are:
+    <ul>
+        <li><code><b><font face="Courier New" size="2" color="#333399">"Name"</font></b></code>
+        - Name (menemonic) of the value.
+        <li><code><b><font face="Courier New" size="2" color="#333399">"Value"</font></b></code>
+        - BASE64 encoded binary bits of the value.
+        <li><code><b><font face="Courier New" size="2" color="#333399">"Description"</font></b></code>
+        - Short, human readable description of the value.
+        </ul>
+        <p>
+
+    <li><code><b><font face="Courier New" size="2" color="#333399">"MemoryAddress" : <i>&lt;int&gt;</i></font></b></code>
+    - The address of a memory mapped register. If MemoryContext is provided, the address is referring into that context.
+
+    <li><code><b><font face="Courier New" size="2" color="#333399">"MemoryContext" : <i>&lt;string&gt;</i></font></b></code>
+    - The context ID of a memory context in which a memory mapped register is located. Used together with MemoryAddress to inform where in memory memory mapped registers are located.
+      If absent and MemoryAddress is defined, the context ID of this context is used as default.
+
+    <li><code><b><font face="Courier New" size="2" color="#333399">"CanSearch" : <i>&lt;array of strings&gt;</i></font></b></code>
+    - A list of attribute names which can be searched for starting on this context.
+      If absent the context does not support search.
+
+    <li><code><b><font face="Courier New" size="2" color="#333399">"Role" : <i>&lt;string&gt;</i></font></b></code>
+    - The role the register plays in a program execution.
+
+    <p>Predefined register role strings are:</p>
+    <ul>
+        <li><code><b><font face="Courier New" size="2" color="#333399">"PC"</font></b></code>
+        - Program counter. Defines instruction to execute next.
+
+        <li><code><b><font face="Courier New" size="2" color="#333399">"SP"</font></b></code>
+        - Register defining the current stack pointer location.
+
+        <li><code><b><font face="Courier New" size="2" color="#333399">"FP"</font></b></code>
+        - Register defining the current frame pointer location.
+
+        <li><code><b><font face="Courier New" size="2" color="#333399">"RET"</font></b></code>
+        - Register used to store the return address for calls.
+
+        <li><code><b><font face="Courier New" size="2" color="#333399">"CORE"</font></b></code>
+        - Indicates register or register groups which belong to the core state.
+          Commonly set for general purpose registers,
+          condition code and other registers which are of special
+          interest for determining the state.
+   </ul>
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Registers &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of contexts available for registers access commands.</p>
+ 
+<p>Parent context ID is usually a thread ID retrieved through Run Control Service or one
+of context IDs retrieved by previous getChildren commands.
+Contexts hierarchy can be simple plain list of registers, or it can form a tree of register groups, registers and bit fields.
+It is up to target agent developers to choose layout that is most descriptive for a given target.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;<i></i>
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+
+</font></b></pre>
+
+<h3><a name='CmdSetRegister'>Set Register</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Registers &bull; set &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;string: value&gt;</i> &bull;
+</font></b></pre>
+
+<p>Writes value into given register context. Context ID must be one returned by getContexts.
+Value is BASE64 encoded byte array of binary data. Array size should match the size of the register.</p>
+  
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error.</p>
+
+<h3><a name='CmdGetRegister'>Get Register</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Registers &bull; get &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>Reads register value from given register context. Context ID must be one returned by getContexts.
+</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;string: value&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error. Value is BASE64 encoded byte array of binary data. Array size should match the size of the register.</p>
+
+<h3><a name='CmdSetMultiple'>Set Multiple Registers</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Registers &bull; setm &bull; <i>&lt;array of locations&gt;</i> &bull; <i>&lt;string: value&gt;</i> &bull;
+
+<i>&lt;array of locations&gt;</i>
+    &rArr; [ <i>&lt;location list&gt;</i> ]
+
+<i>&lt;location list&gt;</i>
+    &rArr; <i>&lt;location&gt;</i>
+    &rArr; <i>&lt;location list&gt;</i> , <i>&lt;location&gt;</i>
+  
+<i>&lt;location&gt;</i>
+    &rArr; [ <i>&lt;string: register context ID&gt;</i> , <i>&lt;int: offset in bytes&gt;</i> , <i>&lt;int: size in bytes&gt;</i> ]
+</font></b></pre>
+
+<p>Writes value into given list of locations in registers. Each location is represented by 3-element array that consists of
+context ID, offset in the context in bytes and value size in bytes.
+Value is BASE64 encoded byte array of binary data. Byte array size should match the sum of location sizes.</p>
+  
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error.</p>
+
+<h3><a name='CmdGetMultiple'>Get Multiple Registers</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; &lt;token&gt; &bull; Registers &bull; getm &bull; <i>&lt;array of locations&gt;</i> &bull;
+
+<i>&lt;array of locations&gt;</i>
+    &rArr; [ <i>&lt;location list&gt;</i> ]
+
+<i>&lt;location list&gt;</i>
+    &rArr; <i>&lt;location&gt;</i>
+    &rArr; <i>&lt;location list&gt;</i> , <i>&lt;location&gt;</i>
+  
+<i>&lt;location&gt;</i>
+    &rArr; [ <i>&lt;string: register context ID&gt;</i> , <i>&lt;int: offset in bytes&gt;</i> , <i>&lt;int: size in bytes&gt;</i> ]
+</font></b></pre>
+
+<p>Reads register values from given list of locations in registers. Each location is represented by 3-element array that consists of
+context ID, offset in the context in bytes and value size in bytes.
+</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;string: value&gt;</i> &bull;
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation
+of error. Value is BASE64 encoded byte array of binary data. Byte array size should match the sum of location sizes.</p>
+
+<h3><a name='CmdSearch'>Search for Registers</a></h3>
+ 
+<pre><b><font face="Courier New" size="2" color="#333399">
+C &bull; &lt;token&gt; &bull; Registers &bull; search &bull; <i>&lt;string: start context ID&gt; &bull; &lt;object:filter properties&gt;</i> &bull;
+</font></b></pre>
+
+<p>Search returns a path to each context with properties matching the filter. A path consists of a list of 
+    context ids starting with a direct child of the start context up to the found context.
+    Search is only supported for properties listed in the CanSearch property.
+
+<p>Predefined filter object properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size="2" color="#333399">"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - The name of the property this filter applies to. Must be one of the names listed in the CanSearch property.
+        </li>
+    <li><code><b><font face="Courier New" size="2" color="#333399">"EqualValue" : <i>&lt;string&gt;</i></font></b></code>
+    - The value which is searched for.
+        </li>
+</ul>
+</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size="2" color="#333399">
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context Paths&gt;</i> &bull;
+
+<i>&lt;array of context Paths&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context Path list&gt;</i> ]
+  
+<i>&lt;context Path list&gt;</i>
+    &rArr; <i>&lt;array of context IDs&gt;</i>
+    &rArr; <i>&lt;context Path list&gt;</i> , <i>&lt;array of context IDs&gt;</i>
+
+</font></b></pre>
+
+<p>Error report provides integer error code and a short, human readable explanation of error.
+In the result, each matching context is provided with the path of parents starting with the direct
+children of the starting node up to the matching node.
+Multiple found entries are returned as an array of those paths.
+</p>
+Example Assume the following context hierarchy:
+
+<pre><b><font face="Courier New" size="2">
+{"Name" : "Core", "ID":"ID_C"}
+        {"Name" : "Group0", "ID":"ID_G0", "Role":"CORE"}
+                {"Name" : "PC", "ID":"ID_PC", "Role":"PC"}
+                {"Name" : "SP", "ID":"ID_SP", "Role":"SP"}
+        {"Name" : "Group1", "ID":"ID_G1"}
+                {"Name" : "R0", "ID":"ID_R0"}
+</font></b></pre>
+
+With this setup, the following commands and responses could take place:
+
+<pre><b><font face="Courier New" size="2">
+C &bull; "1234" &bull; Registers &bull; search &bull; "ID_C" &bull; {"Name":"Name", "EqualValue":"PC"} &bull;
+R &bull; "1234" &bull; [["ID_G0", "ID_PC"]] &bull;
+
+C &bull; "1235" &bull; Registers &bull; search &bull; "ID_C" &bull; {"Name":"Role", "EqualValue":"CORE"} &bull;
+R &bull; "1235" &bull; [["ID_G0"]] &bull;
+</font></b></pre>
+
+<h2><a name='Events'>Events</a></h2>
+ 
+<p>Registers service broadcasts notification events when registers contexts are changed, and when
+a register content is altered by "set" commands.</p>
+ 
+<pre><b><font face="Courier New" size="2" color="#333399">
+E &bull; Registers &bull; contextChanged &bull;
+E &bull; Registers &bull; registerChanged &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#3F5FBF>/**
+ * IRegisters service provides access to target CPU register values and properties.
+ */</font>
+<font color=#7F0055>public interface</font> IRegisters <font color=#7F0055>extends</font> IService {
+
+    <font color=#7F0055>static final</font> String NAME = "Registers";
+
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        PROP_ID = "ID",                         <font color=#3F5FBF>/** String, ID of the context */</font>
+        PROP_PARENT_ID = "ParentID",            <font color=#3F5FBF>/** String, ID of a parent context */</font>
+        PROP_PROCESS_ID = "ProcessID",          <font color=#3F5FBF>/** String, process ID */</font>
+        PROP_NAME = "Name",                     <font color=#3F5FBF>/** String, context name */</font>
+        PROP_DESCRIPTION = "Description",       <font color=#3F5FBF>/** String, context description */</font>
+        PROP_SIZE = "Size",                     <font color=#3F5FBF>/** Number, context size in bytes. Byte arrays in get/set commands should be same size */</font>
+        PROP_READBLE = "Readable",              <font color=#3F5FBF>/** Boolean, true if context value can be read */</font>
+        PROP_READ_ONCE = "ReadOnce",            <font color=#3F5FBF>/** Boolean, true if reading the context (register) destroys its current value */</font>
+        PROP_WRITEABLE = "Writeable",           <font color=#3F5FBF>/** Boolean, true if context value can be written */</font>
+        PROP_WRITE_ONCE = "WriteOnce",          <font color=#3F5FBF>/** Boolean, true if register value can not be overwritten - every write counts */</font>
+        PROP_SIDE_EFFECTS = "SideEffects",      <font color=#3F5FBF>/** Boolean, true if writing the context can change values of other registers */</font>
+        PROP_VOLATILE = "Volatile",             <font color=#3F5FBF>/** Boolean, true if the register value can change even when target is stopped */</font>
+        PROP_FLOAT = "Float",                   <font color=#3F5FBF>/** Boolean, true if the register value is a floating-point value */</font>
+        PROP_BIG_ENDIAN = "BigEndian",          <font color=#3F5FBF>/** Boolean, true if big endian */</font>
+        PROP_LEFT_TO_RIGHT = "LeftToRight",     <font color=#3F5FBF>/** Boolean, true if the lowest numbered bit should be shown to user as the left-most bit */</font>
+        PROP_FIST_BIT = "FirstBit",             <font color=#3F5FBF>/** Number, bit numbering base (0 or 1) to use when showing bits to user */</font>
+        PROP_BITS = "Bits",                     <font color=#3F5FBF>/** Number, if context is a bit field, contains the field bit numbers in the parent context */</font>
+        PROP_VALUES = "Values",                 <font color=#3F5FBF>/** Array of Map, predefined names (mnemonics) for some of context values */</font>
+        PROP_MEMORY_ADDRESS = "MemoryAddress",  <font color=#3F5FBF>/** Number, the address of a memory mapped register */</font>
+        PROP_MEMORY_CONTEXT = "MemoryContext",  <font color=#3F5FBF>/** String, the context ID of a memory context in which a memory mapped register is located */</font>
+        PROP_CAN_SEARCH = "CanSearch",          <font color=#3F5FBF>/** Array of String, a list of attribute names which can be searched for starting on this context */</font>
+        PROP_ROLE = "Role";                     <font color=#3F5FBF>/** String, the role the register plays in a program execution */</font>
+    
+    <font color=#3F5FBF>/**
+     * Role property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        ROLE_PC = "PC",                         <font color=#3F5FBF>/** Program counter. Defines instruction to execute next */</font>
+        ROLE_SP = "SP",                         <font color=#3F5FBF>/** Register defining the current stack pointer location */</font>
+        ROLE_FP = "FP",                         <font color=#3F5FBF>/** Register defining the current frame pointer location */</font>
+        ROLE_RET = "RET",                       <font color=#3F5FBF>/** Register used to store the return address for calls */</font>
+        ROLE_CORE = "CORE";                     <font color=#3F5FBF>/** Indicates register or register groups which belong to the core state */</font>
+    
+    <font color=#3F5FBF>/**
+     * Filter property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        SEARCH_NAME = "Name",                   <font color=#3F5FBF>/** The name of the property this filter applies too */</font>
+        SEARCH_EQUAL_VALUE = "EqualValue";      <font color=#3F5FBF>/** The value which is searched for */</font>
+
+
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context ID.
+     *   
+     * <font color=#7F9FBF>@param</font> id &ndash; context ID. 
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getContext(String id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; context data.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, RegistersContext context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve contexts available for registers commands.
+     * A context corresponds to an execution thread, stack frame, registers group, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service.
+     *  
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID. Can be null &ndash;
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getChildren commands.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getChildren().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context_ids &ndash; array of available context IDs.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    <font color=#3F5FBF>/**
+     * RegistersContext objects represent register groups, registers and bit fields. 
+     */</font>
+    <font color=#7F0055>interface</font> RegistersContext {
+        <font color=#3F5FBF>/**
+         * Get Context ID.
+         * <font color=#7F9FBF>@return</font> context ID.
+         */</font>
+        String getID();
+        
+        <font color=#3F5FBF>/**
+         * Get parent context ID.
+         * <font color=#7F9FBF>@return</font> parent context ID.
+         */</font>
+        String getParentID();
+        
+        <font color=#3F5FBF>/**
+         * Get context (register, register group, bit field) name.
+         * <font color=#7F9FBF>@return</font> context name.
+         */</font>
+        String getName();
+        
+        <font color=#3F5FBF>/**
+         * Get context description.
+         * <font color=#7F9FBF>@return</font> context description.
+         */</font>
+        String getDescription();
+        
+        <font color=#3F5FBF>/**
+         * Get context size in bytes.
+         * Byte arrays in get()/set() methods should be same size.
+         * Hardware register can be smaller then this size, for example in case
+         * when register size is not an even number of bytes. In such case implementation
+         * should add/remove padding that consists of necessary number of zero bits.
+         * @return context size in bytes.
+         */</font>
+        <font color=#7F0055>int</font> getSize();
+        
+        <font color=#3F5FBF>/**
+         * Check if context value can be read.
+         * <font color=#7F9FBF>@return</font> true if can read value of the context.
+         */</font>
+        <font color=#7F0055>boolean</font> isReadable();
+        
+        <font color=#3F5FBF>/**
+         * Check if reading the context (register) destroys its current value -
+         * it can be read only once.
+         * <font color=#7F9FBF>@return</font> true if read-once register.
+         */</font>
+        <font color=#7F0055>boolean</font> isReadOnce();
+        
+        <font color=#3F5FBF>/**
+         * Check if context value can be written.
+         * <font color=#7F9FBF>@return</font> true if can write value of the context.
+         */</font>
+        <font color=#7F0055>boolean</font> isWriteable();
+        
+        <font color=#3F5FBF>/**
+         * Check if register value can not be overwritten - every write counts.
+         * <font color=#7F9FBF>@return</font> true if write-once register.
+         */</font>
+        <font color=#7F0055>boolean</font> isWriteOnce();
+        
+        <font color=#3F5FBF>/**
+         * Check if writing the context can change values of other registers. 
+         * <font color=#7F9FBF>@return</font> true if has side effects.
+         */</font>
+        <font color=#7F0055>boolean</font> hasSideEffects();
+        
+        <font color=#3F5FBF>/**
+         * Check if the register value can change even when target is stopped.
+         * <font color=#7F9FBF>@return</font> true if the register value can change at any time.
+         */</font>
+        <font color=#7F0055>boolean</font> isVolatile();
+        
+        <font color=#3F5FBF>/**
+         * Check if the register value is a floating-point value.
+         * <font color=#7F9FBF>@return</font> true if a floating-point register.
+         */</font>
+        <font color=#7F0055>boolean</font> isFloat();
+        
+        <font color=#3F5FBF>/**
+         * Check endianess of the context.
+         * Big endian means decreasing numeric significance with increasing bit number. 
+         * <font color=#7F9FBF>@return</font> true if big endian.
+         */</font>
+        <font color=#7F0055>boolean</font> isBigEndian();
+        
+        <font color=#3F5FBF>/**
+         * Check if the lowest numbered bit (i.e. bit #0 or bit #1 depending on
+         * getFirstBitNumber() value) should be shown to user as the left-most bit or
+         * the right-most bit.
+         * <font color=#7F9FBF>@return</font> true if the first bit is left-most bit.
+         */</font>
+        <font color=#7F0055>boolean</font> isLeftToRight();
+        
+        <font color=#3F5FBF>/**
+         * If the context has bit field children, bit positions of the fields
+         * can be zero-based or 1-based.
+         * <font color=#7F9FBF>@return</font> first bit position - 0 or 1.
+         */</font>
+        <font color=#7F0055>int</font> getFirstBitNumber();
+        
+        <font color=#3F5FBF>/**
+         * If context is a bit field, get the field bit numbers in parent context. 
+         * <font color=#7F9FBF>@return</font> array of bit numbers.
+         */</font>
+        <font color=#7F0055>int</font>[] getBitNumbers();
+        
+        <font color=#3F5FBF>/**
+         * A context can have predefined names (mnemonics) for some its values.
+         * This method returns a list of such named values.
+         * <font color=#7F9FBF>@return</font> array of named values or null.
+         */</font>
+        NamedValue[] getNamedValues();
+        
+        <font color=#3F5FBF>/**
+         * Get the address of a memory mapped register.
+         * <font color=#7F9FBF>@return</font> address.
+         */</font>
+        Number getMemoryAddress();
+        
+        <font color=#3F5FBF>/**
+         * Get the context ID of a memory context in which a memory mapped register is located. 
+         * <font color=#7F9FBF>@return</font> memory context ID.
+         */</font>
+        String getMemoryContext();
+        
+        <font color=#3F5FBF>/**
+         * Get a list of property names which can be searched for starting on this context
+         * <font color=#7F9FBF>@return</font> collection of property names.
+         */</font>
+        Collection<String> canSearch();
+        
+        <font color=#3F5FBF>/**
+         * Get the role the register plays in a program execution.
+         * <font color=#7F9FBF>@return</font> role name.
+         */</font>
+        String getRole();
+
+        <font color=#3F5FBF>/**
+         * Get complete map of context properties.
+         * <font color=#7F9FBF>@return</font> map of all available context properties.
+         */</font>
+        Map<String,Object> getProperties();
+        
+        <font color=#3F5FBF>/**
+         * Read value of the context.
+         * <font color=#7F9FBF>@param</font> done - call back object.
+         * <font color=#7F9FBF>@return</font> - pending command handle.
+         */</font>
+        IToken get(DoneGet done);
+        
+        <font color=#3F5FBF>/**
+         * Set value of the context.
+         * <font color=#7F9FBF>@param</font> value - value to write into the context.
+         * <font color=#7F9FBF>@param</font> done - call back object.
+         * <font color=#7F9FBF>@return</font> - pending command handle.
+         */</font>
+        IToken set(byte[] value, DoneSet done);
+
+       <font color=#3F5FBF>/**
+         * Search register contexts that passes given search filter.
+         * Search is only supported for properties listed in the "CanSearch" property.
+         * <font color=#7F9FBF>@param</font> filter - properties bag that defines search filter.
+         * <font color=#7F9FBF>@param</font> done - call back object.
+         * <font color=#7F9FBF>@return</font> - pending command handle.
+         */</font>
+         IToken search(Map&lt;String,Object&gt; filter, DoneSearch done);
+    }
+
+    <font color=#3F5FBF>/**
+     * A register context can have predefined names (mnemonics) for some its values.
+     * NamedValue objects represent such values. 
+     */</font>
+    <font color=#7F0055>interface</font> NamedValue {
+        <font color=#3F5FBF>/**
+         * Get value associated with the name.
+         * <font color=#7F9FBF>@return</font> the value as an array of bytes.
+         */</font>
+        byte[] getValue();
+        
+        <font color=#3F5FBF>/**
+         * Get name (mnemonic) of the value.
+         * <font color=#7F9FBF>@return</font> value name.
+         */</font>
+        String getName();
+        
+        <font color=#3F5FBF>/**
+         * Get human readable description of the value.
+         * <font color=#7F9FBF>@return</font> value description.
+         */</font>
+        String getDescription();
+    }
+    
+    <font color=#3F5FBF>/**
+     * Read values of multiple locations in registers.
+     * <font color=#7F9FBF>@param</font> locs - array of data locations.
+     * <font color=#7F9FBF>@param</font> done - call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken getm(Location[] locs, DoneGet done);
+    
+    <font color=#3F5FBF>/**
+     * Set values of multiple locations in registers.
+     * <font color=#7F9FBF>@param</font> locs - array of data locations.
+     * <font color=#7F9FBF>@param</font> value - value to write into the context.
+     * <font color=#7F9FBF>@param</font> done - call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken setm(Location[] locs, byte[] value, DoneSet done);
+
+    <font color=#3F5FBF>/**
+     * Class Location represents value location in register context
+     */</font>
+    <font color=#7F0055>final class</font> Location {
+        <font color=#3F5FBF>/** Register context ID */</font>
+        <font color=#7F0055>public final</font> String id; 
+
+        <font color=#3F5FBF>/** offset in the context, in bytes */</font>
+        <font color=#7F0055>public final int</font> offs;
+
+        <font color=#3F5FBF>/** value size in bytes */</font>
+        <font color=#7F0055>public final int</font> size;
+
+        <font color=#7F0055>public</font> Location(String id, <font color=#7F0055>int</font> offs, <font color=#7F0055>int</font> size) {
+            <font color=#7F0055>this</font>.id = id;
+            <font color=#7F0055>this</font>.offs = offs;
+            <font color=#7F0055>this</font>.size = size;
+        }
+    }
+
+    <font color=#3F5FBF>/**
+     * 'get' command call back interface.
+     */</font>
+    <font color=#7F0055>interface</font> DoneGet {
+        <font color=#3F5FBF>/**
+         * Called when value retrieval is done.
+         * <font color=#7F9FBF>@param</font> token - command handle
+         * <font color=#7F9FBF>@param</font> error - error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> value - context value as array of bytes.
+         */</font>
+        <font color=#7F0055>void</font> doneGet(IToken token, Exception error, byte[] value);
+    }
+    
+    <font color=#3F5FBF>/**
+     * 'set' command call back interface.
+     */</font>
+    <font color=#7F0055>interface</font> DoneSet {
+        <font color=#3F5FBF>/**
+         * Called when value setting is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error description if operation failed, null if succeeded.
+         */</font>
+        <font color=#7F0055>void</font> doneSet(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * 'search' command call back interface.
+     */</font>
+    <font color=#7F0055>interface</font> DoneSearch {
+        <font color=#3F5FBF>/**
+         * Called when context search is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> paths - array of paths to each context with properties matching the filter
+         */</font>
+        <font color=#7F0055>void</font> doneSearch(IToken token, String[][] paths);
+    }
+
+    <font color=#3F5FBF>/**
+     * Add registers service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> addListener(RegistersListener listener);
+
+    <font color=#3F5FBF>/**
+     * Remove registers service event listener.
+     * <font color=#7F9FBF>@param</font> listener - event listener implementation.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(RegistersListener listener);
+
+    <font color=#3F5FBF>/**
+     * Registers event listener is notified when registers context hierarchy
+     * changes, and when a register is modified by the service commands. 
+     */</font>
+    <font color=#7F0055>interface</font> RegistersListener {
+
+        <font color=#3F5FBF>/**
+         * Called when register context properties changed.
+         * Most targets have static set of registers and register properties.
+         * Such targets never generate this event. However, some targets,
+         * for example, JTAG probes, allow user to modify register definitions.
+         * Clients should flush all cached register context data. 
+         */</font>
+        <font color=#7F0055>void</font> contextChanged();
+
+        <font color=#3F5FBF>/**
+         * Called when register content was changed and clients 
+         * need to update themselves. Clients, at least, should invalidate
+         * corresponding cached registers data.
+         * Not every change is notified - it is not possible,
+         * only those, which are not caused by normal execution of the debuggee.
+         * At least, changes caused by "set" command should be notified.
+         * <font color=#7F9FBF>@param</font> id - register context ID.
+         */</font>
+        <font color=#7F0055>void</font> registerChanged(String context_id);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Run Control.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,709 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Run Control</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Run Control</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+        <li><a href='#CmdSuspend'>Suspend</a>
+        <li><a href='#CmdResume'>Resume</a>
+        <li><a href='#CmdGetState'>Get State</a>
+        <li><a href='#CmdTerminate'>Terminate</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Run Control Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>The service provides basic run control operations for execution contexts on a target.
+Command and event parameters are encoded as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+ 
+<p>All run control commands are fully asynchronous, which means they never wait until
+context is in a particular state. For example, if single step command arrives when
+context is running, it does not wait until it stops, but returns an error. If a command
+successfully resumed a context, it does not wait until instruction pointer reaches
+desired destination &ndash; from client point of view the command execution ends right after
+context was resumed. Various stepping commands can leave a context running in a special
+mode, which is different from normal execution, for example, it can leave temporary
+breakpoints to suspend the context when control reaches a particular place. Such execution
+mode ends when the context is suspended, even if it was suspended for reasons unrelated
+to the command and intended destination was not reached. Client can know when and
+why a context is suspended by listening to events.</p>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; getContext &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves context properties for given context ID.
+Exact meaning of context depends on the target. 
+A context can represent an execution thread, a process, an address space, etc.
+A context can belong to a parent context. Contexts hierarchy can be simple
+plain list or it can form a tree. It is up to target agent developers to choose
+layout that is most descriptive for a given target. Context IDs are valid across
+all services. In other words, all services access same hierarchy of contexts,
+with same IDs, however, each service accesses its own subset of context's
+attributes and functionality, which is relevant to that service.</p>
+
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object: context properties&gt;</i>
+</font></b></pre>
+
+<p>Context data object is collection of context properties. It should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b>.
+It can also contain arbitrary number of components
+describing context properties and capabilities. Context data is supposed to be cached
+by clients and it is not expected to change frequently. It can include, for example,
+context name or ability to perform single step command on the context. But, it should
+not include volatile data like current PC or running/suspended state. Service sends
+contextChanged event to notify changes in context data.</p>
+
+<p>Predefined run control context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of a parent context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"IsContainer" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the context is a container.
+    Executing resume or suspend command on a container causes all its children to resume or suspend.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"HasState" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if the context is an execution context, therefore
+    has an execution state, like state of a program counter (PC).
+    Only context that has a state can be resumed or suspended.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CanSuspend" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if Suspend command is supported for this context. It does not mean that the command can be executed successfully in
+    the current state of the context. For example, the command still can fail if context is already suspended.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CanResume" : <i>&lt;int: bitset of resume modes&gt;</i></font></b></code>
+    - for each resume mode, corresponding bit is '1' if Resume command mode is supported for this context, and '0' otherwise.
+    It does not mean that the command can be executed successfully in
+    the current state of the context. For example, the command still can fail if context is already resumed.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CanCount" : <i>&lt;int: bitset of resume modes&gt;</i></font></b></code>
+    - for each resume mode, corresponding bit is '1' if Resume command mode with count other then 1 is supported by the context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CanTerminate" : <i>&lt;boolean&gt;</i></font></b></code>
+    - true if Terminate command is supported by the context,
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests list of execution contexts available for run control commands.</p>
+
+<p>Parent context ID can be null &ndash; to retrieve top level of the hierarchy, can be one
+of context IDs retrieved by previous getChildren commands, or it can be obtained from another service.
+Contexts hierarchy can be simple plain list or it can form a tree. It is up to target agent developers to
+choose layout that is most descriptive for a given target.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+</font></b></pre>
+
+<h3><a name='CmdSuspend'>Suspend</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; suspend &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command suspends execution of given context. The command should fail if CanSuspend property of the context is false.
+If context's IsContainer = true, the command is propagated to context's children. Only contexts with HasState = true
+can be suspended.</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdResume'>Resume</a></h3>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; resume &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: mode&gt;</i> &bull; <i>&lt;int: count&gt;</i> &bull;
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; resume &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: mode&gt;</i> &bull; <i>&lt;int: count&gt;</i> &bull; <i>&lt;object: parameters&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command resumes execution of given context. The command should fail if CanResume
+property of the context is '0' for given mode. If context's IsContainer = true, the command is propagated
+to context's children. Only contexts with HasState = true can be resumed.</p>
+<p>The command can have optional argument that contains set of resume parameters, for example stepping range definition.</p>
+
+<p>Resume modes:</p>
+    <ul>
+        <li>
+            <code>RM_RESUME = 0</code> - resume normal execution. Execution will
+            continue until suspended by command or breakpoint.
+        </li>
+
+        <li>
+            <code>RM_STEP_OVER = 1</code> - step over a single instruction. If instruction
+            is function call, execution continues until control returns from the function.
+        </li>
+
+        <li>
+            <code>RM_STEP_INTO = 2</code> - single instruction in given context.
+        </li>
+
+        <li>
+            <code>RM_STEP_OVER_LINE = 3</code> - resume execution of given context until control reaches instruction
+            that belongs to a different line of source code, but runs any functions called at
+            full speed. Error is returned if line number information not available.
+        </li>
+
+        <li>
+            <code>RM_STEP_INTO_LINE = 4</code> - resumes execution of given context until control reaches instruction
+            that belongs to a different line of source code. If a function is called,
+            stop at first line of the function code. Error is returned if line number
+            information not available.
+        </li>
+
+        <li>
+            <code>RM_STEP_OUT = 5</code> - resume execution of given context until control returns from current
+            function.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_RESUME = 6</code> - reverse of <code>RM_RESUME</code>; resume backward execution. Execution will
+            continue until suspended by command or breakpoint.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_OVER = 7</code> - reverse of <code>RM_STEP_OVER</code>; reverse step over a single instruction.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_INTO = 8</code> - reverse of <code>RM_STEP_INTO</code>; reverse step into a single instruction in the given context.
+            This effectively "un-executes" the previous instruction.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_OVER_LINE = 9</code> - reverse of <code>RM_STEP_OVER_LINE</code>; resume backward execution
+            of given context until control reaches an instruction that belongs to a different source line.
+            If the line contains a function call then don't stop until get out of the function.
+            Error is returned if line number information not available.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_INTO_LINE = 10</code> - reverse of <code>RM_STEP_INTO_LINE</code>; resume backward execution of given context
+            until control reaches an instruction that belongs to a different line of source code.
+            If a function is called, stop at the beginning of the last line of the function code.
+            Error is returned if line number information not available.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_OUT = 11</code> - reverse of <code>RM_STEP_OUT</code>; resume backward execution of
+            the given context until control reaches the point where the current function was called.
+        </li>
+
+        <li>
+            <code>RM_STEP_OVER_RANGE = 12</code> - step over instructions until PC is outside the specified range.
+            If any function call within the range is considered to be in range.
+        </li>
+
+        <li>
+            <code>RM_STEP_INTO_RANGE = 13</code> - step instruction until PC is outside the specified range for any reason.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_OVER_RANGE = 14</code> - reverse of <code>RM_STEP_OVER_RANGE</code>.
+        </li>
+
+        <li>
+            <code>RM_REVERSE_STEP_INTO_RANGE = 15</code> - reverse of <code>RM_STEP_INTO_RANGE</code>.
+        </li>
+    </ul>
+  
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdGetState'>Get State</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; getState &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves current state of the context. The command should fail if HasState property of
+the context is false.</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;boolean: suspended&gt;</i> &bull;
+    <i>&lt;int: PC&gt;</i> &bull; <i>&lt;string: last state change reason&gt;</i> &bull; <i>&lt;state data&gt;</i> &bull;
+
+<i>&lt;state data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object: context state properties&gt;</i>
+</font></b></pre>
+
+<p>State change reason can be any text, but if it is one of predefined strings,
+a generic client might be able to handle it better. Predefined reasons are:</p>
+<ul>
+    <li><code>REASON_USER_REQUEST = "Suspended"</code> - context suspended by command.
+    <li><code>REASON_STEP = "Step"</code> - context resumed or suspended by step command.
+    <li><code>REASON_BREAKPOINT = "Breakpoint"</code> - context suspended by breakpoint.
+    <li><code>REASON_EXCEPTION = "Exception"</code> - context suspended by exception.
+    <li><code>REASON_CONTAINER = "Container"</code> - context suspended or resumed as part of container.
+    <li><code>REASON_WATCHPOINT = "Watchpoint"</code> - context suspended by watchpoint (data breakpoint).
+    <li><code>REASON_SIGNAL = "Signal"</code> - context suspended because it received a signal.
+    <li><code>REASON_SHAREDLIB = "Shared Library"</code> - context suspended because a shared library is loaded or unloaded.
+    <li><code>REASON_ERROR = "Error"</code> - context suspended because of an error in execution environment.
+</ul>
+
+<p>Context state properties can contain any data relevant to context state.
+Definition of state properties depends on a target.</p>
+     
+<h3><a name='CmdTerminate'>Terminate</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; RunControl &bull; terminate &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command terminates execution of given context. The command should fail if CanTerminate
+property of the context is false.</p>
+ 
+<p>Result message:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='Events'>Events</a></h2>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; RunControl &bull; contextAdded &bull; <i>&lt;array of context data&gt;</i> &bull;
+
+E &bull; RunControl &bull; contextChanged &bull; <i>&lt;array of context data&gt;</i> &bull;
+
+E &bull; RunControl &bull; contextRemoved &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+E &bull; RunControl &bull; contextSuspended &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: PC&gt;</i> &bull;
+        <i>&lt;string: reason&gt;</i> &bull; <i>&lt;state data&gt;</i> &bull;
+
+E &bull; RunControl &bull; contextResumed &bull; <i>&lt;string: context ID&gt;</i> &bull;
+
+E &bull; RunControl &bull; contextException &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;string: description&gt;</i> &bull;
+
+E &bull; RunControl &bull; containerSuspended &bull; <i>&lt;string: context ID&gt;</i> &bull; <i>&lt;int: PC&gt;</i> &bull;
+        <i>&lt;string: reason&gt;</i> &bull; <i>&lt;state data&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+E &bull; RunControl &bull; containerResumed &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+<i>&lt;array of context data&gt;</i>
+    &rArr; null
+    &rArr; [ <i>&lt;context data list&gt;</i> ]
+  
+<i>&lt;context data list&gt;</i>
+    &rArr; <i>&lt;object: context data&gt;</i>
+    &rArr; <i>&lt;context data list&gt;</i> , <i>&lt;object: context data&gt;</i>
+</font></b></pre>
+
+<dl>
+    <dt><b>contextAdded</b>
+        <dd>is sent when new contexts are created or attached for debugging. The message contains
+        array of context data. Context data is same as returned by Get Context command.
+    <dt><b>contextChanged</b>
+        <dd>is sent when context properties change. The message contains
+        array of changed (new) context data. Context data is same as returned by Get Context command.
+    <dt><b>contextRemoved</b>
+        <dd>is sent when context is removed - terminated or detached. The message contains
+        array of context IDs.
+    <dt><b>contextSuspended</b>
+        <dd>is sent when context is suspended. The message context ID contains context state data,
+        same state data as returned by Get State command.
+    <dt><b>contextResumed</b>
+        <dd>is sent when context is resumed. The message contains resumed context ID.
+    <dt><b>contextException</b>
+        <dd>is sent when execution exception occurs in a context. The message contains context ID and
+        a string that describes nature of the exception.
+    <dt><b>containerSuspended</b>
+        <dd>is sent when target simultaneously suspends multiple threads in a container (process, core, etc.).
+        The message contains context ID and context state data of a context responsible for the event.
+        It can be container ID or any one of container children, for example, it can be thread
+        that hit "suspend all" breakpoint. Message also contains full list of all contexts that were suspended
+        simultaneously. No separate contextSuspened events are sent for contexts in the list. If client needs
+        state data for those contexts, it should use Get State command.
+    <dt><b>containerResumed</b>
+        <dd>is sent when target simultaneously resumes multiple threads in a container (process,
+        core, etc.). Message contains full list of all contexts that were resumed
+        simultaneously. No separate contextResumed events are sent for contexts in the list.
+</dl>
+
+<h2><a name='API'>API</a></h2>
+
+<pre>
+<font color=#7F0055>public interface</font> IRunControl <font color=#7F0055>extends</font> IService {
+
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        PROP_ID = "ID",
+        PROP_PARENT_ID = "ParentID",
+        PROP_IS_CONTAINER = "IsContainer",
+        PROP_HAS_STATE = "HasState",
+        PROP_CAN_RESUME = "CanResume",
+        PROP_CAN_COUNT = "CanCount",
+        PROP_CAN_SUSPEND = "CanSuspend",
+        PROP_CAN_TERMINATE = "CanTerminate";
+
+    <font color=#3F5FBF>/**
+     * Context resume modes.  
+     */</font>
+    <font color=#7F0055>static final int</font>
+        RM_RESUME = 0,
+        RM_STEP_OVER = 1,
+        RM_STEP_INTO = 2,
+        RM_STEP_OVER_LINE = 3,
+        RM_STEP_INTO_LINE = 4,
+        RM_STEP_OUT = 5,
+        RM_REVERSE_RESUME = 6,
+        RM_REVERSE_STEP_OVER = 7,
+        RM_REVERSE_STEP_INTO = 8,
+        RM_REVERSE_STEP_OVER_LINE = 9,
+        RM_REVERSE_STEP_INTO_LINE = 10,
+        RM_REVERSE_STEP_OUT = 11;
+
+    <font color=#3F5FBF>/**
+     * State change reason of a context.
+     * Reason can be any text, but if it is one of predefined strings,
+     * a generic client might be able to handle it better. 
+     */</font>
+    <font color=#7F0055>static final</font> String
+        REASON_USER_REQUEST = "Suspended",
+        REASON_STEP = "Step",
+        REASON_BREAKPOINT = "Breakpoint",
+        REASON_EXCEPTION = "Exception",
+        REASON_CONTAINER = "Container",
+        REASON_WATCHPOINT = "Watchpoint",
+        REASON_SIGNAL = "Signal",
+        REASON_SHAREDLIB = "Shared Library",
+        REASON_ERROR = "Error";
+
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context ID.
+     *   
+     * <font color=#7F9FBF>@param</font> id &ndash; context ID. 
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getContext(String id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client callback interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; context data.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, RunControlContext context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve children of given context.
+     *   
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID. Can be null &ndash;
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+ 
+    <font color=#3F5FBF>/**
+     * Client callback interface for getContexts().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> contexts &ndash; array of available context IDs.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, RunControlError error, Context[] contexts);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service. 
+     */</font>
+    <font color=#7F0055>interface</font> RunControlContext {
+ 
+        <font color=#3F5FBF>/** 
+         * Retrieve context ID.
+         * Same as getProperties().get("ID")
+         */</font>
+        String getID();
+ 
+        <font color=#3F5FBF>/** 
+         * Retrieve parent context ID.
+         * Same as getProperties().get("ParentID")
+         */</font>
+        String getParentID();
+
+        <font color=#3F5FBF>/**
+         * Get context properties. See PROP_* definitions for property names.
+         * Context properties are read only, clients should not try to modify them.
+         * <font color=#7F9FBF>@return</font> Map of context properties.
+         */</font>
+        Map&lt;String,Object&gt; getProperties();
+ 
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_IS_CONTAINER.
+         * Executing resume or suspend command on a container causes all its children to resume or suspend.
+         * <font color=#7F9FBF>@return</font> value of PROP_IS_CONTAINER.
+         */</font>
+        <font color=#7F0055>boolean</font> isContainer();
+        
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_HAS_STATE.
+         * Only context that has a state can be resumed or suspended. 
+         * <font color=#7F9FBF>@return</font> value of PROP_HAS_STATE.
+         */</font>
+        <font color=#7F0055>boolean</font> hasState();
+        
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_CAN_SUSPEND.
+         * Value 'true' means suspend command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already suspended.
+         * <font color=#7F9FBF>@return</font> value of PROP_CAN_SUSPEND.
+         */</font>
+        <font color=#7F0055>boolean</font> canSuspend();
+        
+        <font color=#3F5FBF>/**
+         * Utility method to read a 'mode' bit in context property PROP_CAN_RESUME.
+         * Value 'true' means resume command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already resumed.
+         * <font color=#7F9FBF>@param</font> mode - resume mode, see RM_*. 
+         * <font color=#7F9FBF>@return</font> value of requested bit of PROP_CAN_RESUME. 
+         */</font>
+        <font color=#7F0055>boolean</font> canResume(<font color=#7F0055>int</font> mode);
+        
+        <font color=#3F5FBF>/**
+         * Utility method to read a 'mode' bit in context property PROP_CAN_COUNT.
+         * Value 'true' means resume command with count other then 1 is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already resumed.
+         * <font color=#7F9FBF>@param</font> mode - resume mode, see RM_*. 
+         * <font color=#7F9FBF>@return</font> value of requested bit of PROP_CAN_COUNT. 
+         */</font>
+        <font color=#7F0055>boolean</font> canCount(<font color=#7F0055>int</font> mode);
+        
+        <font color=#3F5FBF>/**
+         * Utility method to read context property PROP_CAN_TERMINATE.
+         * Value 'true' means terminate command is supported by the context,
+         * however the method does not check that the command can be executed successfully in
+         * the current state of the context. For example, the command still can fail if context is
+         * already exited.
+         * <font color=#7F9FBF>@return</font> value of PROP_CAN_SUSPEND.
+         */</font>
+        <font color=#7F0055>boolean</font> canTerminate();
+
+        <font color=#3F5FBF>/**
+         * Send a command to retrieve current state of a context.
+         * <font color=#7F9FBF>@param</font> done - command result call back object.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken getState(DoneGetState done);
+
+        <font color=#3F5FBF>/**
+         * Send a command to suspend a context.
+         * Also suspends children if context is a container.
+         * <font color=#7F9FBF>@param</font> done - command result call back object.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken suspend(DoneCommand done);
+        
+        <font color=#3F5FBF>/**
+         * Send a command to resume a context.
+         * Also resumes children if context is a container.
+         * <font color=#7F9FBF>@param</font> mode - defines how to resume the context, see RM_*.
+         * <font color=#7F9FBF>@param</font> count - if mode implies stepping, defines how many steps to perform.
+         * <font color=#7F9FBF>@param</font> done - command result call back object.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken resume(<font color=#7F0055>int</font> mode, <font color=#7F0055>int</font> count, DoneCommand done);
+        
+        <font color=#3F5FBF>/**
+         * Send a command to terminate a context.
+         * <font color=#7F9FBF>@param</font> done - command result call back object.
+         * <font color=#7F9FBF>@return</font> pending command handle, can be used to cancel the command.
+         */</font>
+        IToken terminate(DoneCommand done);
+    }
+ 
+    <font color=#7F0055>class</font> RunControlError <font color=#7F0055>extends</font> Exception {
+    }
+ 
+    <font color=#7F0055>interface</font> DoneGetState {
+        <font color=#7F0055>void</font> doneGetState(IToken token, Exception error, <font color=#7F0055>boolean</font> suspended, String pc,
+                String reason, Map&lt;String,Object&gt; params);
+    }
+
+    <font color=#7F0055>interface</font> DoneCommand {
+        <font color=#3F5FBF>/**
+         * Called when run control command execution is complete.
+         * <font color=#7F9FBF>@param</font> token - pending command handle.
+         * <font color=#7F9FBF>@param</font> error - command execution error or null.
+         */</font>
+        <font color=#7F0055>void</font> doneCommand(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Add run control event listener.
+     * <font color=#7F9FBF>@param</font> listener - run control event listener to add.
+     */</font>
+    <font color=#7F0055>void</font> addListener(RunControlListener listener);
+    
+    <font color=#3F5FBF>/**
+     * Remove run control event listener.
+     * <font color=#7F9FBF>@param</font> listener - run control event listener to remove.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(RunControlListener listener);
+
+    <font color=#3F5FBF>/**
+     * Service events listener interface.
+     */</font>
+    <font color=#7F0055>interface</font> RunControlListener {
+
+        <font color=#3F5FBF>/**
+         * Called when a new contexts are created.
+         * <font color=#7F9FBF>@param</font> contexts - array of new context properties.
+         */</font>
+        <font color=#7F0055>void</font> contextAdded(RunControlContext contexts[]);
+
+        <font color=#3F5FBF>/**
+         * Called when a context properties changed.
+         * <font color=#7F9FBF>@param</font> contexts - array of new context properties.
+         */</font>
+        <font color=#7F0055>void</font> contextChanged(RunControlContext contexts[]);
+
+        <font color=#3F5FBF>/**
+         * Called when contexts are removed.
+         * <font color=#7F9FBF>@param</font> context_ids - array of removed context IDs.
+         */</font>
+        <font color=#7F0055>void</font> contextRemoved(String context_ids[]);
+
+        <font color=#3F5FBF>/**
+         * Called when a thread is suspended.
+         * <font color=#7F9FBF>@param</font> context - ID of a context that was suspended.
+         * <font color=#7F9FBF>@param</font> pc - program counter of the context, can be null.
+         * <font color=#7F9FBF>@param</font> reason - human readable description of suspend reason.
+         * <font color=#7F9FBF>@param</font> params - additional, target specific data about suspended context.
+         */</font>
+        <font color=#7F0055>void</font> contextSuspended(String context, String pc,
+                String reason, Map&lt;String,Object&gt; params);
+
+        <font color=#3F5FBF>/**
+         * Called when a thread is resumed.
+         * <font color=#7F9FBF>@param</font> context - ID of a context that was resumed.
+         */</font>
+        <font color=#7F0055>void</font> contextResumed(String context);
+
+        <font color=#3F5FBF>/**
+         * Called when target simultaneously suspends multiple threads in a container
+         * (process, core, etc.).
+         * 
+         * <font color=#7F9FBF>@param</font> context - ID of a context responsible for the event. It can be container ID or
+         * any one of container children, for example, it can be thread that hit "suspend all" breakpoint.
+         * Client expected to move focus (selection) to this context.
+         * <font color=#7F9FBF>@param</font> pc - program counter of the context.
+         * <font color=#7F9FBF>@param</font> reason - human readable description of suspend reason.
+         * <font color=#7F9FBF>@param</font> params - additional target specific data about suspended context.
+         * <font color=#7F9FBF>@param</font> suspended_ids - full list of all contexts that were suspended. 
+         */</font>
+        <font color=#7F0055>void</font> containerSuspended(String context, String pc,
+                String reason, Map&lt;String,Object&gt; params, String[] suspended_ids);
+
+        <font color=#3F5FBF>/**
+         * Called when target simultaneously resumes multiple threads in a container (process,
+         * core, etc.).
+         * 
+         * <font color=#7F9FBF>@param</font> context_ids - full list of all contexts that were resumed. 
+         */</font>
+        <font color=#7F0055>void</font> containerResumed(String[] context_ids);
+
+        <font color=#3F5FBF>/**
+         * Called when an exception is detected in a target thread.
+         * <font color=#7F9FBF>@param</font> context - ID of a context that caused an exception.
+         * <font color=#7F9FBF>@param</font> msg - human readable description of the exception.
+         */</font>
+        <font color=#7F0055>void</font> contextException(String context, String msg);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Stack Trace.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,295 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Stack Trace</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Stack Trace</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Stack Trace Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>The service implements thread stack back tracing. Command
+and event parameters are encoded as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; StackTrace &bull; getContext &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+</font></b></pre>
+
+<p>The command retrieves context info for given context IDs.
+Command allows to query multiple contexts at once.
+Stack Trace context represents single stack frame.
+If target supports more then one stack per thread,
+each stack is also represented by a separate context.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;array of context data&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; 
+
+<i>&lt;array of context data&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context data list&gt;</i> ]
+  
+<i>&lt;context data list&gt;</i>
+    &rArr; <i>&lt;context data&gt;</i>
+    &rArr; <i>&lt;context data list&gt;</i> , <i>&lt;context data&gt;</i>
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Context data object should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;.</i></font></b>
+Context data is expected to be cached by clients.
+Cached context data should by flushed when parent thread is resumed.</p>
+
+<p>Predefined stack trace context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of a parent context.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ProcessID" : <i>&lt;string&gt;</i></font></b></code>
+    - process ID.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - context name if context is a stack
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"FP" : <i>&lt;number&gt;</i></font></b></code>
+    - frame pointer - memory address of stack frame
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"PC" : <i>&lt;number&gt;</i></font></b></code>
+    - program counter - memory address of instruction that will be executed when thread returns from this stack frame.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ArgsCnt" : <i>&lt;number&gt;</i></font></b></code>
+    - function arguments count
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ArgsAddr" : <i>&lt;number&gt;</i></font></b></code>
+    - memory address of function arguments
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Level" : <i>&lt;number&gt;</i></font></b></code>
+    - frame level. Bottom most (oldest) frame is level 0.
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; StackTrace &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves stack trace context list.
+Parent context usually corresponds to an execution thread.
+Some targets have more then one stack. In such case children of a thread
+are stacks, and stack frames are deeper in the hierarchy - they can be
+retrieved with additional getChildren commands.</p>
+ 
+<p>The command will fail if parent thread is not suspended.
+Client can use Run Control service to suspend a thread.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;<i></i>
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+
+</font></b></pre>
+
+
+<h2><a name='Events'>Events</a></h2>
+ 
+<p>No events are currently defined for Stack Trace service.</p>
+ 
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#7F0055>public interface</font> IStackTrace <font color=#7F0055>extends</font> IService {
+
+    <font color=#7F0055>static final</font> String NAME = "StackTrace";
+
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        PROP_ID = "ID",
+        PROP_PARENT_ID = "ParentID",
+        PROP_PROCESS_ID = "ProcessID",
+        PROP_NAME = "Name",
+        PROP_FRAME_ADDRESS = "FP",
+        PROP_PROGRAM_COUNTER = "PC",
+        PROP_ARGUMENTS_COUNT = "ArgsCnt",
+        PROP_ARGUMENTS_ADDRESS = "ArgsAddr",
+        PROP_LEVEL = "Level";
+
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context IDs.
+     * 
+     * The command will fail if parent thread is not suspended.
+     * Client can use Run Control service to suspend a thread.
+     *   
+     * <font color=#7F9FBF>@param</font> id &ndash; array of context IDs. 
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getContext(String[] id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when context data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; array of context data or null if error.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, StackTraceContext[] context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve stack trace context list.
+     * Parent context usually corresponds to an execution thread.
+     * Some targets have more then one stack. In such case children of a thread
+     * are stacks, and stack frames are deeper in the hierarchy - they can be
+     * retrieved with additional getChildren commands.
+     * 
+     * The command will fail if parent thread is not suspended.
+     * Client can use Run Control service to suspend a thread.
+     *  
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID.
+     * <font color=#7F9FBF>@param</font> done - call back interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    <font color=#3F5FBF>/**
+     * Client call back interface for getChildren().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when context list retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context_ids &ndash; array of available context IDs.
+         * Stack frames are ordered from stack bottom to top.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    <font color=#3F5FBF>/**
+     * StackTraceContext represents stack trace objects - stacks and stack frames. 
+     */</font>
+    <font color=#7F0055>interface</font> StackTraceContext {
+        
+        <font color=#3F5FBF>/**
+         * Get Context ID.
+         * <font color=#7F9FBF>@return</font> context ID.
+         */</font>
+        String getID();
+        
+        <font color=#3F5FBF>/**
+         * Get parent context ID.
+         * <font color=#7F9FBF>@return</font> parent context ID.
+         */</font>
+        String getParentID();
+        
+        <font color=#3F5FBF>/**
+         * Get context name - if context represents a stack.
+         * <font color=#7F9FBF>@return</font> context name or null.
+         */</font>
+        String getName();
+        
+        <font color=#3F5FBF>/**
+         * Get memory address of this frame.
+         * <font color=#7F9FBF>@return</font> address or null if not a stack frame.
+         */</font>
+        Number getFrameAddress();
+        
+        <font color=#3F5FBF>/**
+         * Get program counter saved in this stack frame -
+         * it is address of instruction to be executed when the function returns.
+         * <font color=#7F9FBF>@return</font> program counter or null if not a stack frame.
+         */</font>
+        Number getProgramCounter();
+        
+        <font color=#3F5FBF>/**
+         * Get number of function arguments for this frame.
+         * <font color=#7F9FBF>@return</font> function arguments count.
+         */</font>
+        <font color=#7F0055>int</font> getArgumentsCount();
+        
+        <font color=#3F5FBF>/**
+         * Get address of function arguments area in memory.
+         * <font color=#7F9FBF>@return</font> function arguments address or null if not available.
+         */</font>
+        Number getArgumentsAddress();
+        
+        <font color=#3F5FBF>/**
+         * Get stack frame level.
+         * <font color=#7F9FBF>@return</font> frame level or 0 if not a stack frame.
+         */</font>
+        <font color=#7F0055>int</font> getLevel();
+
+        <font color=#3F5FBF>/**
+         * Get complete map of context properties.
+         * <font color=#7F9FBF>@return</font> map of context properties.
+         */</font>
+        Map&lt;String,Object&gt; getProperties();
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - Streams.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,417 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - Streams</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - Streams</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdSubscribe'>Subscribe</a>
+        <li><a href='#CmdUnsubscribe'>Unsubscribe</a>
+        <li><a href='#CmdRead'>Read</a>
+        <li><a href='#CmdWrite'>Write</a>
+        <li><a href='#CmdEOS'>End of Stream</a>
+        <li><a href='#CmdConnect'>Connect</a>
+        <li><a href='#CmdDisconnect'>Disconnect</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>Streams Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2009-03-17
+        <td>Initial contribution
+    <tr>
+        <td>0.2
+        <td>2009-05-18
+        <td>Added connect command
+    <tr>
+        <td>0.3
+        <td>2009-08-13
+        <td>Added "context ID" argument in "created" event
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>Streams service is a generic interface to support streaming of data between host and remote agents.
+
+<p>The service supports:
+<ul>
+    <li> Asynchronous overlapped data streaming: multiple 'read' or 'write' command can be issued at same time, both peers
+         can continue data processing concurrently with data transmission.
+    <li> Multicast: multiple clients can receive data from same stream.
+    <li> Subscription model: clients are required to expressed interest in particular streams by subscribing for the service.
+    <li> Flow control: peers can throttle data flow of individual streams by delaying 'read' and 'write' commands.   
+</ul>
+
+<p> Command and event parameters are encoded as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdSubscribe'>Subscribe</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; subscribe &bull; <i>&lt;string: stream source type&gt;</i> &bull;
+</font></b></pre>
+
+<p>Clients must subscribe for one or more stream source types to be able to send or receive stream data.
+Stream source type name are defined by other services that use streams to transfer data.
+For example, <a href='TCF Service - Processes.html'>Processes Service</a> defines
+"Processes" strem source that represents standard input/output streams.
+Subscribers receive notifications when a stream of given type is created or disposed.
+Subscribers are required to respond with 'read' or 'disconnect' commands as necessary.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<p>If no error is reported, the client becomes a subscriber of streams of the given type - until channel is closed or
+the subscribtion is canceled by <b>unsubscribe</b> command.
+When new stream is created, each subscriber must decide if it is interested in that particular stream instance.
+If not interested, subscriber should send 'disconnect' command to allow remote peer to free resources and bandwidth allocated for the stream.
+If not disconnected, subscriber is required to send 'read' commands as necessary to pump stream data and prevent stream buffer overflow.
+</p>
+
+<h3><a name='CmdUnsubscribe'>Unsubscribe</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; unsubscribe &bull; <i>&lt;string: stream source type&gt;</i> &bull;
+</font></b></pre>
+
+<p>Unsubscribe the client from given stream source type.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdRead'>Read</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; read &bull; <i>&lt;string: stream ID&gt;</i> &bull; <i>&lt;int: size&gt;</i> &bull;
+</font></b></pre>
+
+<ul>
+    <li><dt><code><b>stream ID</b></code> <dd>ID of stream that will be read.
+    <li><dt><code><b>size</b></code> <dd>Maximum number of bytes to read.
+</ul>
+
+<p>The command reads data from a stream. If stream buffer is empty, the command will wait until data is available.
+Remote peer will continue to process other commands while 'read' command is pending.
+Client can send more 'read' commands without waiting for the first command to complete.
+Doing that improves communication channel bandwidth utilization.
+Pending 'read' commands will be executed in same order as issued.
+Client can delay sending of 'read' command if it is not ready to receive more data,
+however, delaying for too long can cause stream buffer overflow and lost of data.
+.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;string: data&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;int: lost size&gt;</i> &bull; <i>&lt;boolean: EOS&gt;</i> &bull;
+</font></b></pre>
+
+<ul>
+    <li><dt><code><b>data</b></code> <dd>BASE64 encoded bytes that were read from the stream.
+    <li><dt><code><b>lost size</b></code> <dd>Number of bytes that were lost because of buffer overflow.
+             -1 means unknown number of bytes were lost. if both 'lost_size' and 'data.length' are non-zero then lost bytes are considered
+         located right before read bytes. 
+    <li><dt><code><b>EOS</b></code> <dd>true if end of stream was reached.
+</ul>
+
+<h3><a name='CmdWrite'>Write</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; write &bull; <i>&lt;string: stream ID&gt;</i> &bull; <i>&lt;int: size&gt;</i> &bull; <i>&lt;string: data&gt;</i> &bull;
+</font></b></pre>
+
+<ul>
+    <li><dt><code><b>stream ID</b></code> <dd>ID of stream that will receive the data.
+    <li><dt><code><b>size</b></code> <dd>Number of bytes to write. Length of <code><b>data</b></code> must match the size.
+    <li><dt><code><b>data</b></code> <dd>BASE64 encoded bytes that will be written to the stream.
+</ul>
+
+<p>The command writes data to a stream. If stream buffer is full, the command will wait until space is available.
+Remote peer will continue to process other commands while 'write' command is pending.
+Client can send more 'write' commands without waiting for the first command to complete.
+Doing that improves communication channel bandwidth utilization.
+Pending 'write' commands will be executed in same order as issued.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdEOS'>End of Stream</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; eos &bull; <i>&lt;string: stream ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command sends End Of Stream marker to a stream. No more writing to the stream is allowed after that.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdConnect'>Connect</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; connect &bull; <i>&lt;string: stream ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command connects client to a stream. Some data might be dropped from the stream by the time "connect" command is executed.
+Client should be able to re-sync with stream data if it wants to read from such stream.
+If a client wants to read a stream from the beginning it should use "subscribe" command instead of "connect"</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h3><a name='CmdDisconnect'>Disconnect</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Streams &bull; disconnect &bull; <i>&lt;string: stream ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command disconnects client from a stream. Note that disconnect does not destroy the stream, client on other channels can
+continue reading or writing the stream.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='Events'>Events</a></h2>
+ 
+<p>Streams service sends events when a stream is created or disposed. Only clients with active subscribtion will recceive the events.
+Clients can change their subscription with <b>subscribe</b> and <b>unsubscribe</b> commands.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Streams &bull; created &bull; <i>&lt;string: stream type&gt;</i> &bull; <i>&lt;string: stream ID&gt;</i> &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+<p>
+Sent when a new stream is created.
+"stream type" - source type of the stream.
+"stream ID" - ID of the stream.
+"context ID" - a context ID that is associated with the stream, or null.
+</p>
+<p>
+Exact meaning of the context ID depends on stream type.
+Stream types and context IDs are defined by services that use Streams service to transmit data.
+</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Streams &bull; disposed &bull; <i>&lt;string: stream type&gt;</i> &bull; <i>&lt;string: stream ID&gt;</i> &bull;
+</font></b></pre>
+<p>
+Sent when a stream is disposed. 
+"stream type" - source type of the stream.
+"stream ID" - ID of the stream.
+</p>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#7F0055>public interface</font> IStreams extends IService {
+    
+    <font color=#3F5FBF>/**
+     * Service name.
+     */</font>
+    <font color=#7F0055>static final</font> String NAME = "Streams";
+
+    <font color=#3F5FBF>/**
+     * Clients can implement StreamsListener interface to be notified
+     * when a stream is created or disposed. The interface is registered with 'subscribe' command. 
+     * 
+     * When new stream is created, client must decide if it is interested in that particular stream instance.
+     * If not interested, client should send 'disconnect' command to allow remote peer to free resources and bandwidth.
+     * If not disconnected, client is required to send 'read' commands as necessary to prevent stream buffer overflow.
+     */</font>
+    <font color=#7F0055>interface</font> StreamsListener {
+        
+        <font color=#3F5FBF>/**
+         * Called when a new stream is created.
+         * <font color=#7F9FBF>@param</font> stream_type - source type of the stream.
+         * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+         * <font color=#7F9FBF>@param</font> context_id - a context ID that is associated with the stream, or null.
+         * Exact meaning of the context ID depends on stream type.
+         * Stream types and context IDs are defined by services that use Streams service to transmit data.
+         */</font>
+        <font color=#7F0055>void</font> created(String stream_type, String stream_id, String context_id);
+        
+        <font color=#3F5FBF>/**
+         * Called when a stream is disposed. 
+         * <font color=#7F9FBF>@param</font> stream_type - source type of the stream.
+         * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+         */</font>
+        <font color=#7F0055>void</font> disposed(String stream_type, String stream_id);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Clients must subscribe for one or more stream types to be able to send or receive stream data.
+     * Subscribers receive notifications when a stream of given type is created or disposed.
+     * Subscribers are required to respond with 'read' or 'disconnect' commands as necessary.
+     * <font color=#7F9FBF>@param</font> stream_type - the stream source type.
+     * <font color=#7F9FBF>@param</font> listener - client implementation of StreamsListener interface.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken subscribe(String stream_type, StreamsListener listener, DoneSubscribe done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'subscribe' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneSubscribe {
+        <font color=#7F0055>void</font> doneSubscribe(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Unsubscribe the client from given stream source type.
+     * <font color=#7F9FBF>@param</font> stream_type - the stream source type.
+     * <font color=#7F9FBF>@param</font> listener - client implementation of StreamsListener interface.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken unsubscribe(String stream_type, StreamsListener listener, DoneUnsubscribe done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'unsubscribe' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneUnsubscribe {
+        <font color=#7F0055>void</font> doneUnsubscribe(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Read data from a stream. If stream buffer is empty, the command will wait until data is available.
+     * Remote peer will continue to process other commands while 'read' command is pending.
+     * Client can send more 'read' commands without waiting for the first command to complete.
+     * Doing that improves communication channel bandwidth utilization.
+     * Pending 'read' commands will be executed in same order as issued.
+     * Client can delay sending of 'read' command if it is not ready to receive more data,
+     * however, delaying for too long can cause stream buffer overflow and lost of data.
+     * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+     * <font color=#7F9FBF>@param</font> size - max number of bytes to read.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken read(String stream_id, <font color=#7F0055>int</font> size, DoneRead done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'read' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneRead {
+        <font color=#3F5FBF>/**
+         * Called when 'read' command is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error object or null.
+         * <font color=#7F9FBF>@param</font> lost_size - number of bytes that were lost because of buffer overflow.
+         * 'lost_size' -1 means unknown number of bytes were lost.
+         * if both 'lost_size' and 'data.length' are non-zero then lost bytes are considered
+         * located right before read bytes. 
+         * <font color=#7F9FBF>@param</font> data - bytes read from the stream.
+         * <font color=#7F9FBF>@param</font> eos - true if end of stream was reached.
+         */</font>
+        <font color=#7F0055>void</font> doneRead(IToken token, Exception error, <font color=#7F0055>int</font> lost_size, <font color=#7F0055>byte</font>[] data, boolean eos);
+    }
+
+    <font color=#3F5FBF>/**
+     * Write data to a stream. If stream buffer is full, the command will wait until space is available.
+     * Remote peer will continue to process other commands while 'write' command is pending.
+     * Client can send more 'write' commands without waiting for the first command to complete.
+     * Doing that improves communication channel bandwidth utilization.
+     * Pending 'write' commands will be executed in same order as issued.
+     * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+     * <font color=#7F9FBF>@param</font> buf - buffer that contains stream data.
+     * <font color=#7F9FBF>@param</font> offset - byte offset in the buffer.
+     * <font color=#7F9FBF>@param</font> size - number of bytes to write.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken write(String stream_id, <font color=#7F0055>byte</font>[] buf, <font color=#7F0055>int</font> offset, <font color=#7F0055>int</font> size, DoneWrite done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'write' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneWrite {
+        <font color=#3F5FBF>/**
+         * Called when 'write' command is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error object or null.
+         */</font>
+        <font color=#7F0055>void</font> doneWrite(IToken token, Exception error);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Send End Of Stream marker to a stream. No more writing to the stream is allowed after that. 
+     * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken eos(String stream_id, DoneEOS done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'eos' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneEOS {
+        <font color=#3F5FBF>/**
+         * Called when 'eos' command is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error object or null.
+         */</font>
+        <font color=#7F0055>void</font> doneEOS(IToken token, Exception error);
+    }
+
+    <font color=#3F5FBF>/**
+     * Disconnect client from a stream.
+     * <font color=#7F9FBF>@param</font> stream_id - ID of the stream.
+     * <font color=#7F9FBF>@param</font> done - command result call back object.
+     * <font color=#7F9FBF>@return</font> - pending command handle.
+     */</font>
+    IToken disconnect(String stream_id, DoneDisconnect done);
+    
+    <font color=#3F5FBF>/**
+     * Call back interface for 'disconnect' command.
+     */</font>
+    <font color=#7F0055>interface</font> DoneDisconnect {
+        <font color=#3F5FBF>/**
+         * Called when 'disconnect' command is done.
+         * <font color=#7F9FBF>@param</font> token - command handle.
+         * <font color=#7F9FBF>@param</font> error - error object or null.
+         */</font>
+        <font color=#7F0055>void</font> doneDisconnect(IToken token, Exception error);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Service - System Monitor.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,671 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services - System Monitor</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services - System Monitor</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Cmds'>Commands</a>
+    <ul>
+        <li><a href='#CmdGetContext'>Get Context</a>
+        <li><a href='#CmdGetChildren'>Get Children</a>
+        <li><a href='#CmdGetCommandLine'>Get Command Line</a>
+        <li><a href='#CmdGetEnvironment'>Get Environment</a>
+    </ul>
+    <li><a href='#Events'>Events</a>
+    <li><a href='#API'>API</a>
+</ul>
+
+<h1>System Monitor Service</h1>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+<p>The service can be used for monitoring system activity and utilization.
+It provides list of running processes, different process attributes like command line, environment, etc.,
+and some resource utilization data. The service can be used by a client to provide functionality
+similar to Unix 'top' utility or Windows 'Task Manager'.</p>
+
+<p>Command and event parameters are encoded
+as zero terminated <a href='TCF Specification.html#JSON'>JSON</a> strings.</p>
+
+<p>The service uses standard format for error reports,
+see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p>
+ 
+<h2><a name='Cmds'>Commands</a></h2>
+
+<h3><a name='CmdGetContext'>Get Context</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; SysMonitor &bull; getContext &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command retrieves context info for given context ID.
+A context corresponds to an execution thread or process.
+Context IDs are valid across TCF services, so it is allowed to issue 'SysMonitor.getContext'
+command with a context that was obtained from another service.</p>
+ 
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;context data&gt;</i> &bull;
+
+<i>&lt;context data&gt;</i>
+    &rArr; null
+    &rArr; <i>&lt;object&gt;</i>
+</font></b></pre>
+
+<p>Context data object should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;.</i></font></b>
+</p>
+
+<p>Predefined context properties are:</p>
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the context, same as getContext command argument.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ParentID" : <i>&lt;string&gt;</i></font></b></code>
+    - parent context ID.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CWD" : <i>&lt;string&gt;</i></font></b></code>
+    - current working directory of the process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Root" : <i>&lt;string&gt;</i></font></b></code>
+    - the process's root directory (as set by chroot).
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"UID" : <i>&lt;int&gt;</i></font></b></code>
+    - User ID of the process owner.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"UGID" : <i>&lt;int&gt;</i></font></b></code>
+    - Group ID of the process owner.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"UserName" : <i>&lt;string&gt;</i></font></b></code>
+    - user name of the process owner.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"GroupName" : <i>&lt;string&gt;</i></font></b></code>
+    - group name of the process owner.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"PID" : <i>&lt;int&gt;</i></font></b></code>
+    - system process ID.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"File" : <i>&lt;string&gt;</i></font></b></code>
+    - executable file of the process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"State" : <i>&lt;string&gt;</i></font></b></code>
+    - one character from the string "RSDZTW"  where  R  is  running,  S  is
+    sleeping  in  an  interruptible wait, D is waiting in uninterruptible
+    disk sleep, Z is zombie, T is traced or stopped (on a signal), and  W
+    is paging.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"PPID" : <i>&lt;int&gt;</i></font></b></code>
+    - system ID of the parent process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"PGRP" : <i>&lt;int&gt;</i></font></b></code>
+    - the process group ID of the process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Session" : <i>&lt;int&gt;</i></font></b></code>
+    - the session ID of the process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"TTY" : <i>&lt;int&gt;</i></font></b></code>
+    - the tty the process uses.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"TGID" : <i>&lt;int&gt;</i></font></b></code>
+    - the process group ID of the process which currently owns the tty that
+    the process is connected to.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"TracerPID" : <i>&lt;int&gt;</i></font></b></code>
+    - ID of a process that has attached this process for tracing or debugging.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Flags" : <i>&lt;int&gt;</i></font></b></code>
+    - the kernel flags word of the process. Details depend on the kernel.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"MinFlt" : <i>&lt;int&gt;</i></font></b></code>
+    - the  number  of  minor  faults  the  process  has made which have not
+    required loading a memory page from disk.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CMinFlt" : <i>&lt;int&gt;</i></font></b></code>
+    - the number of minor faults that  the  process's  waited-for  children have made.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"MajFlt" : <i>&lt;int&gt;</i></font></b></code>
+    - the  number  of major faults the process has made which have required
+    loading a memory page from disk.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CMajFlt" : <i>&lt;int&gt;</i></font></b></code>
+    - the number of major faults that  the  process's  waited-for  children
+    have made.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"UTime" : <i>&lt;int&gt;</i></font></b></code>
+    - the number of milliseconds that this process has been scheduled in user mode.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"STime" : <i>&lt;int&gt;</i></font></b></code>
+    - the number of milliseconds that this process has been scheduled in kernel mode.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CUTime" : <i>&lt;int&gt;</i></font></b></code>
+    - the  number  of  jiffies that this process's waited-for children have
+    been scheduled in user mode.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CSTime" : <i>&lt;int&gt;</i></font></b></code>
+    - the  number  of  jiffies that this process's waited-for children have
+    been scheduled in user mode.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Priority" : <i>&lt;int&gt;</i></font></b></code>
+    - the standard nice value.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Nice" : <i>&lt;int&gt;</i></font></b></code>
+    - the nice value.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ITRealValue" : <i>&lt;int&gt;</i></font></b></code>
+    - the time in milliseconds before the next SIGALRM is sent  to  the  process
+    due to an interval timer.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StartTime" : <i>&lt;int&gt;</i></font></b></code>
+    - the time in milliseconds the process started after system boot.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"VSize" : <i>&lt;int&gt;</i></font></b></code>
+    - virtual memory size in bytes.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"PSize" : <i>&lt;int&gt;</i></font></b></code>
+    - memory pages size in bytes.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"RSS" : <i>&lt;int&gt;</i></font></b></code>
+    - resident  Set  Size:  number of pages the process has in real memory,
+    minus used for administrative purposes. This is  just  the  pages  which
+    count  towards  text,  data,  or  stack space.  This does not include
+    pages which have not been demand-loaded in, or which are swapped out.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"RLimit" : <i>&lt;int&gt;</i></font></b></code>
+    - current  limit in bytes on the rss of the process.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CodeStart" : <i>&lt;int&gt;</i></font></b></code>
+    - the address above which program text can run.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CodeEnd" : <i>&lt;int&gt;</i></font></b></code>
+    - the address below which program text can run.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"StackStart" : <i>&lt;int&gt;</i></font></b></code>
+    - the address of the start of the stack.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Signals" : <i>&lt;int&gt;</i></font></b></code>
+    - the bitmap of pending signals.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"SigBlock" : <i>&lt;int&gt;</i></font></b></code>
+    - the bitmap of blocked signals.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"SigIgnore" : <i>&lt;int&gt;</i></font></b></code>
+    - the bitmap of ignored signals.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"SigCatch" : <i>&lt;int&gt;</i></font></b></code>
+    - the bitmap of caught signals.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"WChan" : <i>&lt;int&gt;</i></font></b></code>
+    - this  is  the  "channel"  in which the process is waiting.  It is the
+    address of a system call, and can be looked up in a namelist  if  you
+    need  a  textual  name.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"NSwap" : <i>&lt;int&gt;</i></font></b></code>
+    - number of pages swapped.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"CNSwap" : <i>&lt;int&gt;</i></font></b></code>
+    - cumulative NSwap for child processes.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ExitSignal" : <i>&lt;int&gt;</i></font></b></code>
+    - signal to be sent to parent when this process exits.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Processor" : <i>&lt;int&gt;</i></font></b></code>
+    - CPU number last executed on.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"RTPriority" : <i>&lt;int&gt;</i></font></b></code>
+    - real-time scheduling priority.
+        
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Policy" : <i>&lt;int&gt;</i></font></b></code>
+    - scheduling policy.
+</ul>
+
+<h3><a name='CmdGetChildren'>Get Children</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; SysMonitor &bull; getChildren &bull; <i>&lt;string: parent context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of contexts available for System Monitor commands.</p>
+ 
+<p>Parent context ID can be null &ndash; to retrieve top level of the hierarchy, can be one
+of context IDs retrieved by previous getChildren commands, or it can be obtained from another service.
+Contexts hierarchy can be simple plain list or it can form a tree. It is up to target agent developers to
+choose layout that is most descriptive for a given target.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of context IDs&gt;</i> &bull;
+
+<i>&lt;array of context IDs&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;context ID list&gt;</i> ]
+  
+<i>&lt;context ID list&gt;</i>
+    &rArr; <i>&lt;string: context ID&gt;</i>
+    &rArr; <i>&lt;context ID list&gt;</i> , <i>&lt;string: context ID&gt;</i>
+</font></b></pre>
+
+<h3><a name='CmdGetCommandLine'>Get Command Line</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; SysMonitor &bull; getCommandLine &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of progess command line arguments.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of string&gt;</i> &bull;
+
+<i>&lt;array of string&gt;</i>
+    &rArr; null
+    &rArr; [ ]
+    &rArr; [ <i>&lt;string list&gt;</i> ]
+  
+<i>&lt;string list&gt;</i>
+    &rArr; <i>&lt;string&gt;</i>
+    &rArr; <i>&lt;string list&gt;</i> , <i>&lt;string&gt;</i>
+</font></b></pre>
+
+<h3><a name='CmdGetEnvironment'>Get Environment</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; SysMonitor &bull; getEnvironment &bull; <i>&lt;string: context ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command requests a list of progess environment variables.</p>
+ 
+<p>Reply:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull; <i>&lt;array of string&gt;</i> &bull;
+</font></b></pre>
+
+<h2><a name='Events'>Events</a></h2>
+
+<p>No events are currently defined for System Monitor service.</p>
+
+<h2><a name='API'>API</a></h2>
+ 
+<pre>
+<font color=#7F0055>public interface</font> ISysMonitor <font color=#7F0055>extends</font> IService {
+
+   <font color=#7F0055>static final</font> String NAME = "SysMonitor";
+
+    <font color=#3F5FBF>/**
+     * Retrieve context info for given context ID.
+     *   
+     * <font color=#7F9FBF>@param</font> id &ndash; context ID. 
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getContext(String id, DoneGetContext done);
+
+    <font color=#3F5FBF>/**
+     * Client callback interface for getContext().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetContext {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context &ndash; context data.
+         */</font>
+        <font color=#7F0055>void</font> doneGetContext(IToken token, Exception error, SysMonitorContext context);
+    }
+
+    <font color=#3F5FBF>/**
+     * Retrieve children of given context.
+     *   
+     * <font color=#7F9FBF>@param</font> parent_context_id &ndash; parent context ID. Can be null &ndash;
+     * to retrieve top level of the hierarchy, or one of context IDs retrieved
+     * by previous getContext or getChildren commands. 
+     * <font color=#7F9FBF>@param</font> done - callback interface called when operation is completed.
+     */</font>
+    IToken getChildren(String parent_context_id, DoneGetChildren done);
+
+    <font color=#3F5FBF>/**
+     * Client callback interface for getChildren().
+     */</font>
+    <font color=#7F0055>interface</font> DoneGetChildren {
+        <font color=#3F5FBF>/**
+         * Called when contexts data retrieval is done.
+         * <font color=#7F9FBF>@param</font> error &ndash; error description if operation failed, null if succeeded.
+         * <font color=#7F9FBF>@param</font> context_ids &ndash; array of available context IDs.
+         */</font>
+        <font color=#7F0055>void</font> doneGetChildren(IToken token, Exception error, String[] context_ids);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Context property names.
+     */</font>
+    <font color=#7F0055>static final</font> String
+        <font color=#3F5FBF>/** The TCF context ID */</font>
+        PROP_ID = "ID",
+        
+        <font color=#3F5FBF>/** The TCF parent context ID */</font>
+        PROP_PARENTID = "ParentID",
+        
+        <font color=#3F5FBF>/** Current working directory of the process */</font>
+        PROP_CWD = "CWD",
+        
+        <font color=#3F5FBF>/** The process's root directory (as set by chroot) */</font>
+        PROP_ROOT = "Root",
+        
+        <font color=#3F5FBF>/** User ID of the process owner */</font>
+        PROP_UID = "UID",
+        
+        <font color=#3F5FBF>/** Group ID of the process owner */</font>
+        PROP_UGID = "UGID",
+        
+        <font color=#3F5FBF>/** User name of the process owner */</font>
+        PROP_USERNAME = "UserName",
+        
+        <font color=#3F5FBF>/** Group name of the process owner */</font>
+        PROP_GROUPNAME = "GroupName",
+        
+        <font color=#3F5FBF>/** System process ID */</font>
+        PROP_PID = "PID",
+        
+        <font color=#3F5FBF>/** Executable file of the process */</font>
+        PROP_FILE = "File",
+        
+        <font color=#3F5FBF>/** One character from the string "RSDZTW"  where  R  is  running,  S  is
+         *  sleeping  in  an  interruptible wait, D is waiting in uninterruptible
+         *  disk sleep, Z is zombie, T is traced or stopped (on a signal), and  W
+         *  is paging.*/</font>
+        PROP_STATE = "State",
+        
+        <font color=#3F5FBF>/** System ID of the parent process */</font>
+        PROP_PPID = "PPID",
+        
+        <font color=#3F5FBF>/** The process group ID of the process */</font>
+        PROP_PGRP = "PGRP",
+        
+        <font color=#3F5FBF>/** The session ID of the process */</font>
+        PROP_SESSION = "Session",
+        
+        <font color=#3F5FBF>/** The tty the process uses */</font>
+        PROP_TTY = "TTY",
+        
+        <font color=#3F5FBF>/** The process group ID of the process which currently owns the tty that
+         *  the process is connected to. */</font>
+        PROP_TGID = "TGID",
+        
+        <font color=#3F5FBF>/** ID of a process that has attached this process for tracing or debugging */</font>
+        PROP_TRACERPID = "TracerPID",
+        
+        <font color=#3F5FBF>/** The kernel flags word of the process. Details depend on the kernel */</font>
+        PROP_FLAGS = "Flags",
+        
+        <font color=#3F5FBF>/** The  number  of  minor  faults  the  process  has made which have not
+         *  required loading a memory page from disk */</font>
+        PROP_MINFLT = "MinFlt",
+        
+        <font color=#3F5FBF>/** The number of minor faults that  the  process's  waited-for  children have made */</font>
+        PROP_CMINFLT = "CMinFlt",       
+        
+        <font color=#3F5FBF>/** The  number  of major faults the process has made which have required
+         *  loading a memory page from disk */</font>
+        PROP_MAJFLT = "MajFlt",
+        
+        <font color=#3F5FBF>/** The number of major faults that  the  process's  waited-for  children
+         *  have made */</font>
+        PROP_CMAJFLT = "CMajFlt",
+        
+        <font color=#3F5FBF>/** The number of milliseconds that this process has been scheduled in user mode */</font>
+        PROP_UTIME = "UTime",
+        
+        <font color=#3F5FBF>/** The number of milliseconds that this process has been scheduled in kernel mode */</font>
+        PROP_STIME = "STime",
+        
+        <font color=#3F5FBF>/** The  number  of  jiffies that this process's waited-for children have
+         *  been scheduled in user mode */</font>
+        PROP_CUTIME = "CUTime",
+        
+        <font color=#3F5FBF>/** The  number  of  jiffies that this process's waited-for children have
+         *  been scheduled in user mode */</font>
+        PROP_CSTIME = "CSTime",
+        
+        <font color=#3F5FBF>/** The standard nice value */</font>
+        PROP_PRIORITY = "Priority",
+        
+        <font color=#3F5FBF>/** The nice value */</font>
+        PROP_NICE = "Nice",
+        
+        <font color=#3F5FBF>/** The time in milliseconds before the next SIGALRM is sent  to  the  process
+         *  due to an interval timer */</font>
+        PROP_ITREALVALUE = "ITRealValue",
+        
+        <font color=#3F5FBF>/** The time in milliseconds the process started after system boot */</font>
+        PROP_STARTTIME = "StartTime",
+        
+        <font color=#3F5FBF>/** Virtual memory size in bytes */</font>
+        PROP_VSIZE = "VSize",
+        
+        <font color=#3F5FBF>/** Memory pages size in bytes */</font>
+        PROP_PSIZE = "PSize",
+        
+        <font color=#3F5FBF>/** Resident  Set  Size:  number of pages the process has in real memory,
+         *  minus used for administrative purposes. This is  just  the  pages  which
+         *  count  towards  text,  data,  or  stack space.  This does not include
+         *  pages which have not been demand-loaded in, or which are swapped out */</font>
+        PROP_RSS = "RSS",
+        
+        <font color=#3F5FBF>/** Current  limit in bytes on the rss of the process */</font>
+        PROP_RLIMIT = "RLimit",
+        
+        <font color=#3F5FBF>/** The address above which program text can run */</font>
+        PROP_CODESTART = "CodeStart",
+        
+        <font color=#3F5FBF>/** The address below which program text can run */</font>
+        PROP_CODEEND = "CodeEnd",
+        
+        <font color=#3F5FBF>/** The address of the start of the stack */</font>
+        PROP_STACKSTART = "StackStart",
+        
+        <font color=#3F5FBF>/** The bitmap of pending signals */</font>
+        PROP_SIGNALS = "Signals",
+        
+        <font color=#3F5FBF>/** The bitmap of blocked signals */</font>
+        PROP_SIGBLOCK = "SigBlock",
+        
+        <font color=#3F5FBF>/** The bitmap of ignored signals */</font>
+        PROP_SIGIGNORE = "SigIgnore",
+        
+        <font color=#3F5FBF>/** The bitmap of caught signals */</font>
+        PROP_SIGCATCH = "SigCatch",
+        
+        <font color=#3F5FBF>/** This  is  the  "channel"  in which the process is waiting.  It is the
+         *  address of a system call, and can be looked up in a name list  if  you
+         *  need  a  textual  name */</font>
+        PROP_WCHAN = "WChan",
+        
+        <font color=#3F5FBF>/** Number of pages swapped */</font>
+        PROP_NSWAP = "NSwap",
+        
+        <font color=#3F5FBF>/** Cumulative NSwap for child processes */</font>
+        PROP_CNSWAP = "CNSwap",
+        
+        <font color=#3F5FBF>/** Signal to be sent to parent when this process exits */</font>
+        PROP_EXITSIGNAL = "ExitSignal",
+        
+        <font color=#3F5FBF>/** CPU number last executed on */</font>
+        PROP_PROCESSOR = "Processor",
+        
+        <font color=#3F5FBF>/** Real-time scheduling priority */</font>
+        PROP_RTPRIORITY = "RTPriority",
+        
+        <font color=#3F5FBF>/** Scheduling policy */</font>
+        PROP_POLICY = "Policy";
+        
+            
+    <font color=#3F5FBF>/**
+     * A context corresponds to an execution thread, process, address space, etc.
+     * A context can belong to a parent context. Contexts hierarchy can be simple
+     * plain list or it can form a tree. It is up to target agent developers to choose
+     * layout that is most descriptive for a given target. Context IDs are valid across
+     * all services. In other words, all services access same hierarchy of contexts,
+     * with same IDs, however, each service accesses its own subset of context's
+     * attributes and functionality, which is relevant to that service. 
+     */</font>
+    <font color=#7F0055>interface</font> SysMonitorContext {
+        
+        <font color=#3F5FBF>/** 
+         * Get context ID.
+         * Same as getProperties().get(&ldquo;ID&rdquo;)
+         */</font>
+        String getID();
+
+        <font color=#3F5FBF>/** 
+         * Get parent context ID.
+         * Same as getProperties().get(&ldquo;ParentID&rdquo;)
+         */</font>
+        String getParentID();
+
+        <font color=#3F5FBF>/** 
+         * Get process group ID.
+         * Same as getProperties().get(&ldquo;PGRP&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getPGRP();
+
+        <font color=#3F5FBF>/** 
+         * Get process ID.
+         * Same as getProperties().get(&ldquo;PID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getPID();
+
+        <font color=#3F5FBF>/** 
+         * Get process parent ID.
+         * Same as getProperties().get(&ldquo;PPID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getPPID();
+
+        <font color=#3F5FBF>/** 
+         * Get process TTY group ID.
+         * Same as getProperties().get(&ldquo;TGID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getTGID();
+
+        <font color=#3F5FBF>/** 
+         * Get tracer process ID.
+         * Same as getProperties().get(&ldquo;TracerPID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getTracerPID();
+
+        <font color=#3F5FBF>/** 
+         * Get process owner user ID.
+         * Same as getProperties().get(&ldquo;UID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getUID();
+
+        <font color=#3F5FBF>/** 
+         * Get process owner user name.
+         * Same as getProperties().get(&ldquo;UserName&rdquo;)
+         */</font>
+        String getUserName();
+
+        <font color=#3F5FBF>/** 
+         * Get process owner user group ID.
+         * Same as getProperties().get(&ldquo;UGID&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getUGID();
+
+        <font color=#3F5FBF>/** 
+         * Get process owner user group name.
+         * Same as getProperties().get(&ldquo;GroupName&rdquo;)
+         */</font>
+        String getGroupName();
+        
+        <font color=#3F5FBF>/** 
+         * Get process state.
+         * Same as getProperties().get(&ldquo;State&rdquo;)
+         */</font>
+        String getState();
+
+        <font color=#3F5FBF>/** 
+         * Get process virtual memory size in bytes.
+         * Same as getProperties().get(&ldquo;VSize&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getVSize();
+
+        <font color=#3F5FBF>/** 
+         * Get process virtual memory page size in bytes.
+         * Same as getProperties().get(&ldquo;PSize&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getPSize();
+
+        <font color=#3F5FBF>/** 
+         * Get number of memory pages in process resident set.
+         * Same as getProperties().get(&ldquo;RSS&rdquo;)
+         */</font>
+        <font color=#7F0055>long</font> getRSS();
+
+        <font color=#3F5FBF>/** 
+         * Get context executable file.
+         * Same as getProperties().get(&ldquo;File&rdquo;)
+         */</font>
+        String getFile();
+
+        <font color=#3F5FBF>/** 
+         * Get context current file system root.
+         * Same as getProperties().get(&ldquo;Root&rdquo;)
+         */</font>
+        String getRoot();
+
+        <font color=#3F5FBF>/** 
+         * Get context current working directory.
+         * Same as getProperties().get(&ldquo;CWD&rdquo;)
+         */</font>
+        String getCurrentWorkingDirectory();
+
+        <font color=#3F5FBF>/**
+         * Get all available context properties.
+         * @return Map 'property name' -> 'property value'
+         */</font>
+        Map&lt;String,Object&gt; getProperties();
+    }
+    
+    <font color=#3F5FBF>/** 
+     * Get context command line.
+     */</font>
+    IToken getCommandLine(String id, DoneGetCommandLine done);
+    
+    <font color=#7F0055>interface</font> DoneGetCommandLine {
+        <font color=#7F0055>void</font> doneGetCommandLine(IToken token, Exception error, String[] cmd_line);
+    }
+
+    <font color=#3F5FBF>/** 
+     * Get context environment variables.
+     */</font>
+    IToken getEnvironment(String id, DoneGetEnvironment done);
+    
+    <font color=#7F0055>interface</font> DoneGetEnvironment {
+        <font color=#7F0055>void</font> doneGetEnvironment(IToken token, Exception error, String[] environment);
+    }
+}
+</pre>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Services.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Services</title>
+</head>
+
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Services</h1>
+ 
+<p>Copyright (c) 2007 Wind River Systems, Inc. Made available under the EPL v1.0
+<p>Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+ 
+<h2>Table of Contents</h2>
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <li><a href='#Syntax'>Syntax Rules Notation</a>
+    <li><a href='#ErrorFormat'>Error Report Format</a>
+    <li><a href='#Services'>Services</a>
+</ul>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+    <tr>
+        <td>1.1
+        <td>2008-06-25
+        <td>Enhanced error reporting format, see <a href='http://bugs.eclipse.org/bugs/show_bug.cgi?id=232410'>Bug 232410</a>
+</table>
+
+<h2><a name='Overview'>Overview</a></h2>
+
+TCF communication model is based on the idea of services. A service is a group of related commands, events and semantics.
+For example, <a href='TCF Service - Memory.html'>Memory Service</a> defines group of command and events for
+reading and writing target memory.
+Service definitions are not part of the <a href='TCF Specification.html'>framework specification</a>, and new services
+are expected to be defined by developers of tools and target agents.
+Defenitions of standard services are provided to achieve certain level of compatibility between tools and targets. 
+ 
+<h2><a name='Syntax'>Syntax Rules Notation</a></h2>
+ 
+<p>Format of the protocol messages is defined by syntax rules. Syntax is described
+using a simple variant of Backus-Naur Form. In particular:</p>
+ 
+<ul type='disc'>
+    <li>Italic lower case words in a courier font, enclosed into angular brackets, are
+    used to denote syntactic categories, for example:&nbsp;<b><i><font face="Courier New" size=2 color=#333399>&lt;token&gt;.
+    </font></i></b>Category name can be followed by colon and a text, which explains semantics
+    of the category, for example: <b><i><font face="Courier New" size=2 color=#333399>&lt;int:
+    error code&gt;</font></i></b> has same meaning as <b><i><font face="Courier New" size=2 color=#333399>&lt;int&gt;</font></i></b>,
+    but denotes that the integer number used to indicate an "error code".
+ 
+    <li>A syntax rule consists of a category designation followed by one or more syntax
+    definitions for the category. The category name and each definition are placed on
+    separate lines, bullets are used to denote definitions, for example:
+</ul>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;chars&gt;</i>
+    &rArr; <i>&lt;char&gt;</i>
+    &rArr; <i>&lt;chars&gt; &lt;char&gt;</i>
+</font></b></pre>
+
+<ul type='disc'>
+    <li>Spaces are added for readability only and they are not part of the syntax.
+ 
+    <li>All text in the category definition, other than categories and spaces, is UTF-8
+    based representation of a message bytes.
+ 
+    <li>The symbol &lsquo;&bull;&rsquo; designates a zero byte. 
+</ul>
+
+<h2><a name='ErrorFormat'>Error Report Format</a></h2>
+
+<p>Most of TCF standard services use same format for error reporting:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;error report&gt;</i>
+    &rArr;
+    &rArr; null
+    &rArr; <i>&lt;object: error description&gt;</i>
+</font></b></pre>
+
+<p>Empty or null error report means success. Error description provides error details, including
+error code and a short, localizable, human readable explanation of the error.</p>
+
+<p>Error description properties are:</p>
+<dl>
+    <dt><b><font face="Courier New" size=2 color=#333399>"Code" : <i>&lt;integer&gt;</i></font></b>
+    <dd>Error code. Can belong to one of predefined ranges:
+        <ul>
+        <li> 0x0-0xffff Standard TCF codes, includes a limited subset of POSIX errors, and OTHER error code, which
+             can be used together with "AltCode"
+        <li> 0x10000-0x1ffff Service specific codes
+        <li> 0x20000-0x2ffff Reserved codes - will never be used by the TCF standard
+        </ul>
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"Time" : <i>&lt;integer&gt;</i></font></b>
+    <dd> Error timestamp, in milliseconds since midnight, January 1, 1970 UTC
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"Service" : <i>&lt;string&gt;</i></font></b>
+    <dd> Name of the service that reported the error. Required when "Code" is service specific code.
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"Format" : <i>&lt;string&gt;</i></font></b>
+    <dd> Error description format supports separation between constant and variable parts
+        of error message ("Format" and "Params"). This is done to support localization.
+        Format string is expected to allow translation into foreign languages by means of string table lookup.
+        The format string syntax is defined in the Java language library
+        <b><font face="Courier New" size=2>java.text.MessageFormat</font></b>.
+        In order to simplify clients written in other languages, only a subset of the syntax is supported:
+         <ul>
+         <li> Supported format types: (none), number
+         <li> Supported format styles:
+             <ul>
+             <li> number: (none), "integer", "percent"
+             </ul>
+         </ul>
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"Params" : <i>&lt;array&gt;</i></font></b>
+    <dd> An array of values to be used together with "Format" to create the error message.
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"Severity" : <i>&lt;integer&gt;</i></font></b>
+    <dd> Predefined severity values:
+        <ul>
+        <li>0 - error (default)
+        <li>1 - warning
+        <li>2 - fatal
+        </ul>
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"AltCode" : <i>&lt;integer&gt;</i></font></b>
+    <dd> Alternative error code.  This can be used to represent,
+    for example, OS, POSIX, or other vendor specific error codes
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"AltOrg" : <i>&lt;string&gt;</i></font></b>
+    <dd> ID of organization defining "AltCode", for example "Linux", "VxWorks", "Wind River", etc
+
+    <dt><b><font face="Courier New" size=2 color=#333399>"CausedBy" : <i>&lt;object: error description&gt;</i></font></b>
+    <dd> A nested error description. Can be used to describe a root cause of this error.
+</dl>
+
+<p>All fields except "Code" are optional.</p>
+
+<p>Standard error codes:
+<pre><code>
+    OTHER               = 1
+    JSON_SYNTAX         = 2
+    PROTOCOL            = 3
+    BUFFER_OVERFLOW     = 4
+    CHANNEL_CLOSED      = 5
+    COMMAND_CANCELLED   = 6
+    UNKNOWN_PEER        = 7
+    BASE64              = 8
+    EOF                 = 9
+    ALREADY_STOPPED     = 10
+    ALREADY_EXITED      = 11
+    ALREADY_RUNNING     = 12
+    ALREADY_ATTACHED    = 13
+    IS_RUNNING          = 14
+    INV_DATA_SIZE       = 15
+    INV_CONTEXT         = 16
+    INV_ADDRESS         = 17
+    INV_EXPRESSION      = 18
+    INV_FORMAT          = 19
+    INV_NUMBER          = 20
+    INV_DWARF           = 21
+    SYM_NOT_FOUND       = 22
+    UNSUPPORTED         = 23
+</code></pre>
+</p>
+
+<p>Service specific error code definitions, if any, are part of service specfications.
+Standard and service specific error codes can be extended over time.  A
+client that does not recognize a specific error code should treat it in the
+same way as "OTHER".</p>
+
+<p>For encoding of <b><i><font face="Courier New" size=2 color=#333399>&lt;object&gt;</font></i></b>,
+<b><i><font face="Courier New" size=2 color=#333399>&lt;string&gt;</font></i></b>, etc., see
+<a href='TCF Specification.html#JSON'>JSON - Preferred Marshaling</a>.
+
+<h2><a name='Services'>Services</h2>
+<ul>
+    <li><a href='TCF Service - Memory.html'>Memory Service</a>
+    <li><a href='TCF Service - Processes.html'>Processes Service</a>
+    <li><a href='TCF Service - Run Control.html'>Run Control Service</a>
+    <li><a href='TCF Service - Registers.html'>Registers Service</a>
+    <li><a href='TCF Service - Stack Trace.html'>Stack Trace Service</a>
+    <li><a href='TCF Service - Breakpoints.html'>Breakpoints Service</a>
+    <li><a href='TCF Service - File System.html'>File System Service</a>
+    <li><a href='TCF Service - System Monitor.html'>System Monitor Service</a>
+    <li><a href='TCF Service - Streams.html'>Streams Service</a>
+</ul>
+
+</body>
+</html>
+ 
Binary file dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Specification Image1.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF Specification.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,1521 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework Specification</title>
+</head>
+<body lang='EN-US'>
+  
+<h1>Target Communication Framework Specification</h1>
+ 
+<p>Copyright (c) 2007, 2008 Wind River Systems, Inc. Made available under the EPL v1.0
+<p>Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+
+<h1>Table of Contents</h1>
+ 
+<ul>
+    <li><a href='#VersionHistory'>Version History</a>
+    <li><a href='#Overview'>Overview</a>
+    <ul>
+        <li><a href='#Goals'>Goals</a>
+        <li><a href='#Definitions'>Definitions</a>
+        <li><a href='#Requirements'>Requirements</a>
+        <li><a href='#Syntax'>Syntax Rules Notation</a>
+    </ul>
+    <li><a href='#Design'>Framework Software Design Considerations</a>
+    <ul>
+        <li><a href='#Concurrency'>Concurrency</a>
+        <li><a href='#Reflection'>Reflection</a>
+        <li><a href='#Ordering'>Message ordering</a>
+    </ul>
+    <li><a href='#Transport'>Transport Layer</a>
+    <li><a href='#Protocol'>Communication Protocol</a>
+    <ul>
+        <li><a href='#ProtocolCommands'>Commands</a>
+        <li><a href='#ProtocolResults'>Results</a>
+        <li><a href='#ProtocolEvents'>Events</a>
+        <li><a href='#ProtocolFlowControl'>Flow Control</a>
+        <li><a href='#ProtocolExamples'>Examples</a>
+    </ul>
+    <li><a href='#API'>API</a>
+    <li><a href='#JSON'>JSON - Preferred Marshaling</a>
+    <ul>
+        <li><a href='#JSONExamples'>JSON - Examples</a>
+    </ul>
+    <li><a href='#Locator'>Locator Service</a>
+    <ul>
+        <li><a href='#LocatorPeer'>Peer Attributes</a>
+        <li><a href='#LocatorCommands'>Locator Service Commands</a>
+        <li><a href='#LocatorEvents'>Locator Service Events</a>
+        <li><a href='#LocatorAPI'>Locator Service API</a>
+    </ul>
+</ul>
+
+<h2><a name='VersionHistory'>Version History</a></h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <th>Version
+        <th>Date
+        <th>Change
+    <tr>
+        <td>0.1
+        <td>2008-01-10
+        <td>Initial contribution
+    <tr>
+        <td>1.0
+        <td>2008-05-06
+        <td>Approved
+    <tr>
+        <td>1.1
+        <td>2009-03-04
+        <td>Added N message
+</table>
+ 
+<h1><a name='Overview'>Overview</a></h1>
+ 
+<p>Today almost every device software development tool on the market has its own method
+of communication with target system. Communication methods often require individual setup,
+configuration and maintenance, impose unnecessary limitations.
+Target Communication Framework goal is to establish common ground in
+the area of communication protocols between development tools and embedded devices.</p>
+ 
+<p>The goal is a single protocol used to communicate between all tools and targets:</p>
+<p><img src='TCF Specification Image1.png'></p>
+ 
+<h2><a name='Goals'>Goals</a></h2>
+ 
+<ul type='disc'>
+    <li>Universal, simple, lightweight, vendor agnostic framework for tools and targets
+    to communicate for purpose of debugging, profiling, code patching and other device
+    software development needs.
+ 
+    <li>Single configuration per target (not per tool per target as today in most cases),
+    or no configuration when possible.
+ 
+    <li>Minimal overhead and footprint on target side.
+</ul>
+
+<h2><a name='Definitions'>Definitions</a></h2>
+
+<dl>
+<dt><b>Peer:</b> <dd>communication endpoint. Both hosts and targets are called peers. A
+peer can act as a client or a server depending on services it implements.
+ 
+<dt><b>Service:</b> <dd>group of related commands, events and semantic define a service.
+A service can be discovered, added or removed as a group at communication endpoint.
+ 
+<dt><b>Message:</b> <dd>a packet of data, formatted according to framework specification
+and transmitted over communication channel.
+ 
+<dt><b>Channel:</b> <dd>communication link connecting two endpoints (peers).  A single
+channel may be used to communicate with multiple services.  Multiple channels may
+be used to connect the same peers, however no command or event ordering is guaranteed
+across channels.
+ 
+<dt><b>Command:</b> <dd>command is a message sent to remote peer in order to request some
+predefined action there.
+ 
+<dt><b>Result:</b> <dd>result is a message sent as a response to a command.
+ 
+<dt><b>Event:</b> <dd>event is a message sent to all interested parties in order to notify
+them about state changes.
+</dl>
+
+<h2><a name='Requirements'>Requirements</a></h2>
+ 
+<ul type='disc'>
+    <li>Simple and extensible protocol.
+ 
+    <li>Small footprint on the target.
+ 
+    <li>Fully asynchronous, message based communication.
+ 
+    <li>Two ways of message routing:
+
+    <ul>
+        <li>Point to point request/response (command/result) communication.
+ 
+        <li>Subscription based broadcast of notifications (events).
+    </ul> 
+ 
+    <li>Full duplex, symmetric communication: both host and target should be able to send
+    commands and events at same time, though ability to establish communication channel
+    can be limited to host only.
+ 
+    <li>For each communication channel between two peers, the framework should preserve
+    order of commands, results and events.
+ 
+    <li>Support for slow and high latency connections.
+ 
+    <li>Transport protocol agnostic. The framework should work well, at least, on top
+    of: TCP/IP, UDP, USB, RS232 and JTAG.
+ 
+    <li>The framework should support multiplexing, that is, single target device shared
+    between multiple tools at same time. To reduce footprint on the target, multiplexing
+    can be implemented on host if needed.
+ 
+    <li>Dynamic discovery of participating targets and hosts. No configuration when possible.
+ 
+    <li>Dynamic discovery of available services (high level protocols, command sets).
+    Clients can query for available services.
+ 
+    <li>Services can be added and removed dynamically.
+ 
+    <li>Framework should define a set of common high level interfaces (services).  For
+    example: flow control, memory access, registers access, up-load mechanism, kernel
+    awareness, run control, target file system, console, flash programming. Implementation
+    of these interfaces is optional, but if provided it will support much wider compatibility
+    with various tools.
+ 
+    <li>Framework should be layered in such a way so it is possible to use different transport
+    medias (e.g. TCP/IP, RS232, USB, etc) without any changes to individual services. 
+    In other words, transport implementation should be services agnostic, and services
+    implementation should be transport agnostic.
+ 
+    <li>Each service defines how marshalling is done for command, result and event arguments.
+    This allows existing target agents to remain unchanged.
+ 
+    <li>Framework should define a preferred marshalling mechanism that new services can
+    use.
+ 
+    <li>The definition of services (groups of related commands and events) is separate
+    from the definition of the framework itself.  The framework provides unified communication
+    mechanism, while services use it to communicate with its clients.
+ 
+    <li>Anybody (including 3rd parties) can add services without having to modify communication
+    protocol or framework software.
+ 
+    <li>The framework should support tunneling through a proxy. Proxy may be used, for
+    example:
+ 
+    <ul type='circle'>
+        <li>to bridge different transport protocols, like TCP and RS232; 
+ 
+        <li>to make a RS232 or USB target connection accessible from multiple hosts; 
+ 
+        <li>to access targets behind firewalls or otherwise not directly accessible
+    </ul>
+ 
+    <li>A proxy should be able to provide services in addition to those implemented by
+    a target. Such distribution of services allows target services to be implemented on
+    a host, thereby reducing the footprint on the target. For example, debug information,
+    stack back trace or OS awareness can be implemented by a proxy on a host. To provide
+    this functionality, proxy services would typically use low-level target services,
+    like memory access.
+ 
+    <li>Supports of concurrent requests. Maximum number of concurrent requests (window
+    size) can be limited on target side. Simple agents only have to support window size
+    of 1. Framework should maintain a queue of additional requests, so tools don't need
+    to know the window size. This may only be relevant for certain transport protocols
+    e.g. UDP.
+ 
+    <li>Events can be broadcasted at any time, i.e. no polling should be required.
+ 
+    <li>Protocol should support a standard mechanism of sending data larger than MTU.
+</ul>
+ 
+<h2><a name='Syntax'>Syntax Rules Notation</a></h2>
+ 
+<p>Format of the protocol messages is defined by syntax rules. Syntax is described
+using a simple variant of Backus-Naur Form. In particular:</p>
+ 
+<ul type='disc'>
+    <li>Italic lower case words in a courier font, enclosed into angular brackets, are
+    used to denote syntactic categories, for example: <b><i><font face="Courier New" size=2 color=#333399>&lt;token&gt;.
+    </font></i></b>Category name can be followed by colon and a text, which explains semantics
+    of the category, for example: <b><i><font face="Courier New" size=2 color=#333399>&lt;int:
+    error code&gt;</font></i></b> has same meaning as <b><i><font face="Courier New" size=2 color=#333399>&lt;int&gt;</font></i></b>,
+    but denotes that the integer number used to indicate an &ldquo;error code&rdquo;.
+ 
+    <li>A syntax rule consists of a category designation followed by one or more syntax
+    definitions for the category. The category name and each definition are placed on
+    separate lines, bullets are used to denote definitions, for example:
+        <pre><b><font face="Courier New" size=2 color=#333399>
+        <i>&lt;chars&gt;</i>
+            &rArr; <i>&lt;char&gt;</i>
+            &rArr; <i>&lt;chars&gt; &lt;char&gt;</i>
+        </font></b></pre>
+
+    <li>Spaces are added for readability only and they are not part of the syntax.
+ 
+    <li>All text in the category definition, other then categories and spaces, is UTF-8
+    based representation of a message bytes.
+ 
+    <li>The symbol &lsquo;&bull;&rsquo; designates a zero byte. 
+</ul>
+ 
+<h1><a name='Design'>Framework Software Design Considerations</a></h1>
+
+<p>The framework will be packaged, distributed and installed on a host as separate
+product. It should be installed as system service and require no configuration for
+most common case &ndash; target connected over TCP or UDP on a local network. For more complicated
+setup, framework should have easily accessible and user friendly GUI with all relevant
+configuration options.</p>
+ 
+<p>Framework should use a dynamic discovery protocol to locate targets and other hosts
+running instances of the framework when possible, and maintain a dynamic list of available
+communication endpoints, as well as lists of services available at each endpoint.
+Host discovery is needed to locate hosts able to proxy communications for targets,
+which are not accessible otherwise - for example, targets connected with RS232 or
+JTAG to a remote host. It should also be possible to add target configuration manually.
+Development tools will access this data through the Locator Service API and use it,
+for example, to present a user a list of available targets that have capabilities
+needed by a particular tool.</p>
+ 
+<p>Framework should provide software libraries to be used by tools and target agents
+developers. The libraries should be available at least for ANSI C and Java. On host
+side, at least Windows, Solaris and Linux must be supported. Libraries will provide
+APIs for low-level communication protocol, Locator Service, preferred marshaling and
+predefined common services.</p>
+ 
+<p>The proposed target communication protocol is text-based. It allows extensions,
+which define messages with blocks of binary data, but it is not a recommended data
+formatting, and its usage is supposed to be limited. Text-based protocols have both
+advantages and disadvantages in compare with binary protocols.</p>
+ 
+<p>Advantages:</p>
+ 
+<ul type='disc'>
+    <li>The software for text-based protocols is easier to develop and debug since they
+    use a relatively human-friendly communication.
+ 
+    <li>It is possible to use huge selection of existing tools and library routines to
+    view, edit, validate, and transform text-based data.
+ 
+    <li>Text based definition is in line with current trend in Internet protocols: most
+    popular protocols such as SMTP and HTTP are text-based.
+</ul>
+ 
+<p>Disadvantages:</p>
+ 
+<ul type='disc'>
+    <li>Text-based protocols usually need more bytes to store numerical data than binary
+    protocols do.
+ 
+    <li>Parsing of text-based data is not efficient compared to parsing of binary data
+    since text-based data is usually not stored in a way similar to how it is stored in
+    computer memory.
+ 
+    <li>It is seldom possible to read only part of a text-based message since the exact
+    byte offset to a data item is generally not known.
+</ul>
+ 
+<p>A possible alternative to consider is binary, variable length encoding like BaseStream.</p>
+ 
+<h2><a name='Concurrency'>Concurrency</a></h2>
+ 
+<p>Concurrent asynchronous communication is much faster then synchronous, because
+it alleviates communication channel latency and allows better bandwidth utilization.
+But it also requires proper design of framework software. Concurrency, in general,
+implies multithreading. However, systems developed with global multithreading, are
+often unreliable and prone to different kinds of thread synchronization problems,
+which are often very difficult to locate and resolve. We therefore strongly recommend
+that the software is designed to follow the compartment threading model, which simplifies
+thread synchronization and promotes reliable software design. In this model each thread
+execution path is strictly contained in predefined subset of code (compartment), and
+no code, except for reentrant libraries, is executed by multiple threads. Each compartment
+has a message queue and other threads communicate with the compartment thread by posting
+messages to the queue.</p>
+ 
+<p>Framework APIs are designed to be compatible with the compartment threading model.
+Hence the API functions do not contain any thread synchronization primitives to protect
+against multiple threads using the functions. All framework APIs belong to a single
+compartment and should be used by a single thread. The same thread is used to dispatch
+events and command results. Concurrency is achieved by declaring API functions to
+be asynchronous. Asynchronous functions do not have any return value, and returns
+immediately, most of the time before the intended job is done. They take additional
+arguments to specify a callback function and callback data. In object-oriented languages
+such as Java, this is typically done by a single callback object argument containing
+both the data and the function.  The result listener is called asynchronously when
+the job is done. This approach is commonly known as asynchronous<b>, </b>event-driven<b>
+</b>or<b> </b>callback-based<b> </b>programming<b>.</b></p>
+ 
+<p>One important characteristic of an asynchronous code is that the methods defined
+by the user will often be called from within the framework itself, rather than from
+the user's application code. The framework often plays the role of the main program
+in coordinating and sequencing application activity. This phenomenon is called Inversion
+of Control (also known as the Hollywood Principle - "Don't call us, we'll call you").</p>
+ 
+<h2><a name='Reflection'>Reflection</a></h2>
+ 
+<p>Communication between development tools and embedded devices must allow a host
+to collect target side data and build a reflection of target state. Reflection is
+usually incomplete &ndash; a subset of all remote data. Reflection is always delayed &ndash; it
+represents a remote peer state in the past. Reflection can be updated by polling for
+data changes or by listening to events (event is communication message that is sent
+asynchronously by a peer to notify others about state change). Reflection is correct
+if it represents a state that actually did happen on remote peer.</p>
+ 
+<p>Reflection is coherent if it is exactly equal to subset of peer state at a single
+moment of time and that moment of time is not too far in the past. Non-coherent reflection
+can have parts of data representing peer state at different moments of time. Coherent
+reflection is more valuable for a user, because non-coherent reflection can have logically
+conflicting data if that data was collected at different time.</p>
+ 
+<p>Traditionally, debuggers would ensure coherence of state reflection by collecting
+data only while target is suspended, and flushing all (or most) reflection data (reducing
+observed subset to zero) when target is resumed. This approach does not work well
+for multithreaded, multicore or real time targets. Maintaining correctness and coherence
+of a non-empty reflection while target is running requires additional support from
+target agent, communication software and debugger itself.</p>
+ 
+<p>Since remote peer state is changing over time, coherent reflection can be built
+only if:</p>
+ 
+<ul type='disc'>
+    <li>Observed subset of state is properly selected and dynamically re-selected. Observing
+    too much can overflow communication channel. Observing too little has little value
+    for a user.
+ 
+    <li>Observer is listening to all relevant events.
+ 
+    <li>Events are coming in exactly same order as corresponding changes happen.
+ 
+    <li>Events are properly ordered relative to other messages that carry state data.
+ 
+    <li>All changes in observed subset of peer state are reported by events.
+ 
+    <li>All event messages must either contain a complete description of a change or they
+    all should not contain any state data at all. If client is getting some data from
+    events and required to retrieve new values of other changed data by using other means
+    (commands), the reflection will not be coherent at least until such retrieval is complete.
+    And if such periods of data retrieval overlap, the reflection will never be coherent.
+    Sending deltas with events is usually more efficient then using data retrieval commands
+    to update reflection.
+</ul>
+ 
+<h2><a name='Ordering'>Message ordering</a></h2>
+ 
+<p>The transmission order of commands, results and events is important, it coveys
+valuable information about target state transitions and it should be preserved when
+possible. Consider an example:</p>
+ 
+<p>Client transmits: </p>
+ 
+<pre>
+    Command X=2
+</pre>
+
+<p>Then, as result of some activity of another client or the target itself, X is assigned
+value 3.</p>
+ 
+<p>Target transmits:</p>
+ 
+<pre>
+    Event X=3
+    Result X=2
+</pre>
+
+<p>Now client has to show value of X to a user. If the order of messages is preserved,
+the client will know that command was executed <i>after</i> X was assigned 3, the
+last message contains last known value of X and 2 is the correct value to show. If
+the target is allowed to transmit events and results in arbitrary order, the client
+will have no clue what to show &ndash; 2 or 3. In fact, the client will have to make a tough
+decision about each message it receives: either trust message data as correct last
+known target state, or assume the message came in out-of-order and ignore it, or re-request
+the information from the target.</p>
+ 
+<p>Note that re-requesting data from the target, in general, does not solve the problem
+of interpretation of messages when order is not preserved. For example, after sending
+a request to read value of X, X could change at about the same time, and client could
+receive:</p>
+ 
+<pre>
+    Event X=2
+    Result X=3
+    Event X=4
+</pre>
+
+<p>If order is not preserved, it is still impossible to tell which value of X is the
+last one. A client could assume value of X unknown every time it receives a notification
+of X change, and then re-request the data again. But this is expensive and, if events
+coming in frequently, client can end up in infinite loop re-requesting the data again
+and again, and it will never have trustworthy data about current target state.</p>
+ 
+<p>Developers should be careful when using multithreading or multiple queues in software
+design &ndash; it can easily cause message reordering.</p>
+ 
+<p>The framework itself is required to preserve message order. However, if for whatever
+reason a target agent cannot preserve message order, the result will be that clients
+of the service can receive messages in the wrong order. When this is the case it should
+be well documented, so tools developers are aware and can make the best of the situation.
+In most cases it will not cause any trouble, but there is no perfect way to restore
+actual sequence of events and maintain data coherency after ordering was lost, and
+in some cases it can severely impact tool functionality and user experience.</p>
+ 
+<h1><a name='Transport'>Transport Layer</a></h1>
+
+ 
+<p>Tools are required to be transport protocol agnostic, so most of the layer functionality
+is used internally by framework and is not exposed to clients. This layer maintains
+a collection of transport protocol handlers. Each handler is designed to provide:</p>
+ 
+<ul type='disc'>
+    <li>Enumeration of available peers, including both automatically discovered and manually
+    configured peers. Handler fires notification events when peers are added or removed.
+    Enumeration can be implemented by scanning JTAG chain, by broadcasting special UDP
+    packet and waiting for responses, by communicating with ICE hardware, or by any other
+    suitable means.
+ 
+    <li>Bidirectional point-to-point communication of data packets. Packets are arrays
+    of bytes of arbitrary size.
+    Transport handler and underlying protocol are responsible for adding all necessary
+    control data, headers, error checking bits, addresses, fragmentation/defragmentation,
+    flow control, transmission retries and whatever necessary to ensure lossless, order-preserving
+    delivery of packets.
+ 
+    <li>Configuration UI should allow user to inspect and modify properties of both manually
+    configured and automatically discovered peers, setup new peers, view connections status
+    and statistics.
+</ul>
+ 
+<p>Existing service discovery protocols can be used together with the framework, for
+example:</p>
+ 
+<ul type='disc'>
+    <li>Zero Configuration Networking (Zeroconf), see <a href='http://www.zeroconf.org/'>http://www.zeroconf.org</a>;
+ 
+    <li>Service Location Protocol (SLP), developed by the IETF;
+ 
+    <li>Jini, which is Sun's Java-base approach to service discovery, see <a href='http://www.sun.com/jini'>http://www.sun.com/jini</a>;
+ 
+    <li>Salutation, developed by an open industry consortium, called the Salutation Consortium;
+ 
+    <li>Microsoft's Universal Plug and Play (UPnP), see <a href='http://www.upnp.org/'>http://www.upnp.org</a>;
+ 
+    <li>Bluetooth Service Discovery Protocol (SDP).
+</ul>
+ 
+<p>Service discovery protocols, as well as transport protocols will be supported by
+framework plug-ins, they are not part of framework code itself, and they can be developed
+by 3rd parties. Note that existing discovery protocols define term &ldquo;service&rdquo; differently
+- as an independent communication endpoint (usually a TCP/IP port). In this document
+it is called &ldquo;peer&rdquo; (host, target, communication endpoint), and a peer can provide
+multiple services over single communication channel.</p>
+  
+<p>Using of standard discovery protocols should be optional, because it can potentially
+cause conflict or interference between development tools and application being developed
+over a use of same standard protocol &ndash; devices software often includes implementation
+of service discovery protocols as part of application code to support their main functions.
+</p>
+
+<h1><a name='Protocol'>Communication Protocol</a></h1>
+
+<p>The communication protocol defines data packets properties and roles common for
+all services. The communication protocol API provides functions for opening and /closing
+of the communication channel for a particular peer, and for sending and receiving
+data packets. The protocol define contents of a part of a packet, the rest of the
+packet is treated as array of bytes at this level. The communication protocol implementation
+also provides:</p>
+ 
+<ul type='disc'>
+    <li>Multiplexing &ndash; opening multiple channels per peer.
+ 
+    <li>Proxy &ndash; packet forwarding in behalf of other hosts.
+</ul>
+  
+<p>Protocol defines three packet types: commands (requests), results (responses),
+and events. Each packet consists of several protocol defined control fields followed
+by byte array of data. Binary representation of control fields is a sequence of zero
+terminated ASCII strings. Format of data array depends on a service. We recommend
+using framework preferred marshaling for data formatting.</p>
+  
+<p>Syntax:</p>
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;message&gt;</i>
+    &rArr; <i>&lt;command&gt;</i>
+    &rArr; <i>&lt;result&gt;</i>
+    &rArr; <i>&lt;event&gt;</i>
+    &rArr; <i>&lt;flow control message&gt;</i>
+</font></b></pre>
+
+<h2><a name='ProtocolCommands'>Commands</a></h2>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;command&gt;</i>
+    &rArr; C &bull; <i>&lt;token&gt; </i>&bull; <i>&lt;service name&gt; </i>&bull; <i>&lt;command name&gt; </i>&bull; <i>&lt;byte array: arguments&gt;</i>
+</font></b></pre>
+
+<p>Command packets start with string &ldquo;C&rdquo;.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;token&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+ 
+<p>Token is unique string generated by framework for each command. It is used to match
+results to commands.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;service name&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+ 
+<p>Service name is used to identify a service that handles the command, it is same
+string as returned by Service.getName().</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;command name&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+ 
+<p>Command name interpretation depends on a service.</p>
+ 
+<p>A command should always be answered with result packed. Result does not have to
+be positive &ndash; it can include an error code, or it can be special "N" result that indicates that command was not recognized,
+but there always must be one. Since client
+cannot detect that a response is missing, if for some reasons peer is not able to
+answer a command, it should consider such situation a fatal communication error and
+it must shutdown the communication channel. It is not necessary to wait for result
+before sending next command. In fact, sending multiple commands in a burst can greatly
+improve performance, especially when connection has high latency. At the same time,
+clients should be carefully designed to avoid flooding the communication channel with
+unlimited number of requests, since this will use resources in forms of memory to
+store the requests and time to process them.</p>
+
+<h2><a name='ProtocolResults'>Results</a></h2>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;result&gt;</i>
+    &rArr; N &bull; <i>&lt;token&gt;</i> &bull;
+    &rArr; R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;byte array: result data&gt;</i>
+    &rArr; P &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;byte array: progress data&gt;</i>
+</font></b></pre>
+
+<p>Result packets start with string &ldquo;P&rdquo; for intermediate result, &ldquo;R&rdquo; for final
+result, and &ldquo;N&rdquo; if command is not recognized. Receiving of &ldquo;R&rdquo; or &ldquo;N&rdquo; result concludes execution of corresponding command.
+There should be exactly one &ldquo;R&rdquo; or &ldquo;N&rdquo; result for each command. In addition, command execution can produce any number of
+intermediate &ldquo;P&rdquo; results. &ldquo;P&rdquo; results can be sent before &ldquo;R&rdquo;, and it can serve, for
+example, as command execution progress report when execution takes long time.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;token&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+ 
+<p>Token should match token field of one of the pending commands that produced the result.</p>
+
+<h2><a name='ProtocolEvents'>Events</a></h2>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;event&gt;</i>
+    &rArr; E &bull; <i>&lt;service name&gt;</i> &bull; <i>&lt;event name&gt;</i> &bull; <i>&lt;byte array: event data&gt;</i>
+</font></b></pre>
+
+<p>Event packets start with string &ldquo;E&rdquo;.</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;service name&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+
+<p>Service name identifies a service that fired event, same string as returned by
+Service.getName().</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;event name&gt;</i>
+    &rArr; <i>&lt;chars&gt;</i>
+</font></b></pre>
+ 
+<p>Event name meaning depends on a service.</p>
+ 
+<p>Events are used to notify clients about changes in peer state. Services should
+provide sufficient variety of events for clients to track remote peer state without
+too much of polling. Clients, interested in a particular aspect of the target state,
+should have a &ldquo;reflection&rdquo; (or &ldquo;model&rdquo;) of that state and update the reflection by
+listening for relevant events. If a service implements a command that changes a particular
+aspect of peers state, then, normally, it should also generate notifications event
+when that same part of the state changes and it should provide a command to retrieve
+current value of the state &ndash; to be used by clients to initialize the reflection. Service
+events are defined statically, together with commands. The framework does not do any
+event processing besides delivering them to clients, however a service can define
+additional event related functionality if necessary, for example, commands for event
+filtering, enabling, disabling, registration, etc. Care should be taken when designing
+events for a service - if events are sent too frequently, they will cause flooding
+of the communication channels and degrade performance. However, too few events will
+force clients to poll for changes and can also degrade performance. A balanced approach
+is the best.</p>
+
+<h2><a name='ProtocolFlowControl'>Flow Control</a> </h2>
+ 
+<p>It often happens that one side of communication channel produces messages faster
+then they can be transmitted over the channel or can be consumed by another side.
+This will cause channel traffic congestion (flooding). Framework will deal with the
+problem and slow down transmitting side by blocking execution inside sendEvent(),
+sendCommand() and sendResult() functions when message buffers are full. However, in
+many cases, it is not the best way to handle congestion. For example, it can make
+a tool UI appear locked for prolonged time or it can break target software if it is
+designed to work in real time. Clients can use flow control events to implement advanced
+techniques to handle traffic congestion, for example, message coalescing, switching
+to less detailed messages, etc.</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;flow control message&gt;</i>
+    &rArr; F &bull; <i>&lt;int: traffic congestion level&gt;</i> &bull;
+</font></b></pre>
+
+<p>Traffic congestion level value is in range &ndash;100..100, where &ndash;100 means no pending
+messages (no traffic), 0 means optimal load, and positive numbers
+indicate level of congestion. When a peer receives flow control message with congestion level > 0
+it should try to reduce its transmition speed.</p>
+
+<h2><a name='ProtocolExamples'>Message Examples</a></h2>
+ 
+<p>Examples use simplified command arguments and result data. See service description
+for actual data formats.</p>
+ 
+<p>Executing <b><i>suspend</i></b> command from <b><i>RunControl</i></b> service:</p>
+ 
+<p>&nbsp;</p>
+ 
+<pre>
+Send   :      C 1 RunControl suspend &ldquo;Thread1&rdquo;
+Receive:      E RunControl suspended &ldquo;Thread1&rdquo;
+Receive:      R 1 &ldquo;Success&rdquo;
+</pre>
+
+<p>Same command, but target was already suspended:</p>
+ 
+<pre>
+Receive:      E RunControl suspended &ldquo;Thread1&rdquo;
+&hellip;
+Send   :      C 2 RunControl suspend &ldquo;Thread1&rdquo;
+Receive:      R 2 &ldquo;Already suspended&rdquo;
+</pre>
+
+<p>Same command, but target was suspended (by another client) after sending the command,
+but before command was executed: </p>
+ 
+<pre>
+Receive:      E RunControl running &ldquo;Thread1&rdquo;
+&hellip;
+Send   :      C 3 RunControl suspend &ldquo;Thread1&rdquo;
+Receive:      E RunControl suspended &ldquo;Thread1&rdquo;
+Receive:      R 3 &ldquo;Already suspended&rdquo;
+</pre>
+
+<h2><a name='API'>Framework API</a></h2>
+ 
+<pre>
+<font color=#3F5FBF>/**
+ * 
+ * Class Protocol provides static methods to access Target Communication Framework root objects:
+ * 1. the framework event queue and dispatch thread;
+ * 2. local instance of Locator service, which maintains a list of available targets;
+ * 3. list of open communication channels.
+ */</font>
+<font color=#7F0055>public class</font> Protocol {
+     
+    <font color=#7F0055>private static</font> IEventQueue <i>event_queue</i>;
+     
+    <font color=#3F5FBF>/**
+     * Before TCF can be used it should be given an object implementing IEventQueue interface.
+     * The implementation maintains a queue of objects implementing Runnable interface and
+     * executes <code>run</code> methods of that objects in a sequence by a single thread.
+     * The thread in referred as TCF event dispatch thread. Objects in the queue are called TCF events.
+     * Executing <code>run</code> method of an event is also called dispatching of event.
+     * 
+     * Only few methods in TCF APIs are thread safe - can be invoked from any thread.
+     * If a method description does not say "can be invoked from any thread" explicitly -  
+     * the method must be invoked from TCF event dispatch thread. All TCF listeners are
+     * invoked from the dispatch thread.
+     * 
+     * <font color=#7F9FBF>@param</font> event_queue - IEventQueue implementation.
+     */</font>
+    <font color=#7F0055>public static void</font> setEventQueue(IEventQueue event_queue);
+    
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> instance of IEventQueue that should be used for TCF events.
+     */</font>
+    <font color=#7F0055>public static</font> IEventQueue getEventQueue();
+    
+    <font color=#3F5FBF>/**
+     * Returns true if the calling thread is TCF dispatch thread.
+     * Use this call to ensure that a given task is being executed (or not being)
+     * on dispatch thread.
+     * This method is thread-safe.
+     *
+     * <font color=#7F9FBF>@return</font> true if running on the dispatch thread.
+     */</font>
+    <font color=#7F0055>public static boolean</font> isDispatchThread();
+    
+    <font color=#3F5FBF>/**
+     * Causes runnable to have its run
+     * method called in the dispatch thread of the framework.
+     * Runnables are dispatched in same order as queued.
+     * If invokeLater is called from the dispatching thread
+     * the <i>runnable.run()</i> will still be deferred until
+     * all pending events have been processed.
+     *
+     * This method can be invoked from any thread.
+     *
+     * <font color=#7F9FBF>@param runnable</font> the Runnable whose run
+     * method should be executed asynchronously.</font>
+     */</font>
+    <font color=#7F0055>public static void</font> invokeLater(Runnable runnable);
+    
+    <font color=#3F5FBF>/**
+     * Causes runnable to have its run
+     * method called in the dispatch thread of the framework.
+     * Calling thread is suspended util the method is executed.
+     * This method is thread-safe.
+     *
+     * <font color=#7F9FBF>@param runnable</font> the Runnable whose run
+     * method should be executed on dispatch thread.
+     */</font>
+    <font color=#7F0055>public static void</font> invokeAndWait(Runnable runnable)
+        <font color=#7F0055>throws</font> InterruptedException;
+    
+    <font color=#3F5FBF>/**
+     * Get instance of the framework locator service.
+     * The service can be used to discover available remote peers.
+     * 
+     * @return instance of ILocator.
+     */</font>
+    <font color=#7F0055>public static</font> ILocator getLocator();
+    
+    <font color=#3F5FBF>/**
+     * Return an array of all open channels.
+     * @return an array of IChannel
+     */</font>
+    <font color=#7F0055>public static</font> IChannel[] getOpenChannels();
+    
+    <font color=#3F5FBF>/**
+     * Interface to be implemented by clients willing to be notified when
+     * new TCF communication channel is opened.
+     */</font>
+    <font color=#7F0055>public interface</font> ChannelOpenListener {
+        <font color=#7F0055>public void</font> onChannelOpen(IChannel channel);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Add a listener that will be notified when new channel is opened.
+     * @param listener
+     */</font>
+    <font color=#7F0055>public static void</font> addChannelOpenListener(ChannelOpenListener listener);
+
+    <font color=#3F5FBF>/**
+     * Remove channel opening listener.
+     * @param listener
+     */</font>
+    <font color=#7F0055>public static void</font> removeChannelOpenListener(ChannelOpenListener listener);
+
+    <font color=#3F5FBF>/**
+     * Transmit TCF event message.
+     * The message is sent to all open communication channels &ndash; broadcasted.
+     */</font>
+    <font color=#7F0055>public static void</font> sendEvent(String service, String name, byte[] data);
+    
+    <font color=#3F5FBF>/**
+     * Call back after TCF messages sent by this host up to this moment are delivered
+     * to their intended target. This method is intended for synchronization of messages
+     * across multiple channels.
+     * 
+     * Note: Cross channel synchronization can reduce performance and throughput.
+     * Most clients don't need cross channel synchronization and should not call this method. 
+     *  
+     * @param done will be executed by dispatch thread after communication 
+     * messages are delivered to corresponding targets.
+     */</font>
+    <font color=#7F0055>public static void</font> sync(Runnable done);
+}
+  
+<font color=#3F5FBF>/**
+ * IChannel represents communication link connecting two endpoints (peers).
+ * The channel asynchroniously transmits messages: commands, results and events.
+ * A single channel may be used to communicate with multiple services.
+ * Multiple channels may be used to connect the same peers, however no command or event
+ * ordering is guaranteed across channels.
+ */</font>
+<font color=#7F0055>public interface</font> IChannel {
+    
+    <font color=#3F5FBF>/**
+     * Channel state IDs
+     */</font>
+    <font color=#7F0055>static final</font> int
+        <i><font color=#0000C0>STATE_OPENNING</font></i> = 0,
+        <i><font color=#0000C0>STATE_OPEN</font></i> = 1,
+        <i><font color=#0000C0>STATE_CLOSED</font></i> = 2;
+    
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> channel current state, see STATE_*
+     */</font>
+    int getState();
+ 
+    <font color=#3F5FBF>/**
+     * Send command message to remote peer for execution. Commands can be queued
+     * locally before transmission. Sending commands too fast can fill up
+     * communication channel buffers. Calling thread will be blocked until
+     * enough buffer space is freed up by transmitting pending messages.
+     * <font color=#7F9FBF>@param</font> service - a remote service that will be sent the command
+     * <font color=#7F9FBF>@param</font> name - command name
+     * <font color=#7F9FBF>@param</font> args - command arguments encoded into array of bytes
+     * <font color=#7F9FBF>@param</font> done - call back object
+     * <font color=#7F9FBF>@return</font> pending command handle 
+     */</font>
+    IToken sendCommand(IService service, String name, <font color=#7F0055>byte</font>[] args,
+        ICommandListener done);
+ 
+    <font color=#3F5FBF>/**
+     * Command listener interface. Clients implement this interface
+     * to receive command results.
+     */</font>
+    <font color=#7F0055>interface</font> ICommandListener {
+        
+        <font color=#3F5FBF>/**
+         * Called when progress message (intermediate result) is received
+         * from remote peer.
+         * <font color=#7F9FBF>@param</font> token - command handle
+         * <font color=#7F9FBF>@param</font> data - progress message arguments encoded into array of bytes
+         */</font>
+        <font color=#7F0055>void</font> progress(<font color=#7F0055>byte</font>[] data);
+        
+        <font color=#3F5FBF>/**
+         * Called when command result received from remote peer.
+         * <font color=#7F9FBF>@param</font> token - command handle
+         * <font color=#7F9FBF>@param</font> data - command result message arguments encoded into array of bytes
+         */</font>
+        <font color=#7F0055>void</font> result(<font color=#7F0055>byte</font>[] data);
+
+        <font color=#3F5FBF>/**
+         * Called when communication channel was closed while command was waiting for result.
+         * <font color=#7F9FBF>@param</font> token - command handle
+         * <font color=#7F9FBF>@param</font> error - exception that forced the channel to close
+         */</font>
+        <font color=#7F0055>void</font> terminated(IToken token, Exception error);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Send result message to remote peer. Messages can be queued locally before
+     * transmission. Sending messages too fast can fill up communication channel
+     * buffers. Calling thread will be blocked until enough buffer space is
+     * freed up by transmitting pending messages.
+     * <font color=#7F9FBF>@param</font> token - command handle
+     * <font color=#7F9FBF>@param</font> results - result message arguments encoded into array of bytes
+     */</font>
+    <font color=#7F0055>void</font> sendResult(IToken token, <font color=#7F0055>byte</font>[] results);
+ 
+    <font color=#3F5FBF>/**
+     * Get current level of outbound traffic congestion.
+     * 
+     * <font color=#7F9FBF>@return</font> integer value in range &ndash;100..100, where &ndash;100 means no pending
+     * messages (no traffic), 0 means optimal load, and positive numbers
+     * indicate level of congestion.
+     * 
+     * Note: in-bound traffic congestion is detected by framework and reported to
+     * remote peer without client needed to be involved. Clients willing to provide
+     * additional data about local congestion should register itself using
+     * Protocol.addCongestionMonitor().
+     */</font>
+    int getCongestion();
+ 
+    <font color=#3F5FBF>/**
+     * Channel listener interface.
+     */</font>
+    <font color=#7F0055>interface</font> IChannelListener {
+ 
+        <font color=#3F5FBF>/**
+         * Called when a channel is opened.
+         */</font>
+        <font color=#7F0055>void</font> onChannelOpened();
+
+        <font color=#3F5FBF>/**
+         * Called when channel closed. If it is closed because of an error,
+         * ‘error’ parameter will describe the error. ‘error’ is null if channel
+         * is closed normally by calling Channel.close().
+         * <font color=#7F9FBF>@param</font> error - channel exception or null
+         */</font>
+        <font color=#7F0055>void</font> onChannelClosed(Throwable error);
+
+        <font color=#3F5FBF>/**
+         * Notifies listeners about congestion level changes. When level &gt; 0
+         * client should delay sending more messages.
+         * <font color=#7F9FBF>@param</font> level - current congestion level
+         */</font>
+        <font color=#7F0055>void</font> congestionLevel(int level);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Subscribe a channel listener. The listener will be notified about changes of
+     * outbound traffic congestion level.
+     * <font color=#7F9FBF>@param</font> listener - channel listener implementation
+     */</font>
+    <font color=#7F0055>void</font> addChannelListener(IChannelListener listener);
+ 
+    <font color=#3F5FBF>/**
+     * Remove a channel listener.
+     * <font color=#7F9FBF>@param</font> listener - channel listener implementation
+     */</font>
+    <font color=#7F0055>void</font> removeChannelListener(IChannelListener listener);
+ 
+    <font color=#3F5FBF>/**
+     * Command server interface.
+     * This interface is to be implemented by service providers.
+     */</font>
+    <font color=#7F0055>interface</font> ICommandServer {
+ 
+        <font color=#3F5FBF>/**
+         * Called every time a command is received from remote peer.
+         * <font color=#7F9FBF>@param</font> token - command handle
+         * <font color=#7F9FBF>@param</font> name - command name
+         * <font color=#7F9FBF>@param</font> data - command arguments encoded into array of bytes
+         */</font>
+        <font color=#7F0055>void</font> command(IToken token, String name, <font color=#7F0055>byte</font>[] data);
+    }
+    
+    <font color=#3F5FBF>/**
+     * Subscribe a command server. The server will be notified about command
+     * messages received through this channel for given service.
+     * <font color=#7F9FBF>@param</font> service - local service implementation
+     * <font color=#7F9FBF>@param</font> server - implementation of service commands listener 
+     */</font>
+    <font color=#7F0055>void</font> addCommandServer(IService service, ICommandServer listener);
+ 
+    <font color=#3F5FBF>/**
+     * Remove a command server.
+     * <font color=#7F9FBF>@param</font> service - local service implementation
+     * <font color=#7F9FBF>@param</font> server - implementation of service commands listener 
+     */</font>
+    <font color=#7F0055>void</font> removeCommandServer(IService service, ICommandServer listener);
+
+    <font color=#3F5FBF>/**
+     * A generic interface for service event listener.
+     * Services usually define a service specific event listener interface,
+     * which is implemented using this generic listener.
+     * Service clients should use service specific listener interface,
+     * unless no such interface is defined.
+     */</font>
+    <font color=#7F0055>interface</font> IEventListener {
+        <font color=#3F5FBF>/**
+         * Called when service event message is received
+         * <font color=#7F9FBF>@param</font> name - event name
+         * <font color=#7F9FBF>@param</font> data - event arguments encode as array of bytes
+         */</font>
+        <font color=#7F0055>void</font> event(String name, <font color=#7F0055>byte</font>[] data);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Subscribe an event message listener for given service.
+     * <font color=#7F9FBF>@param</font> service - remote service proxy
+     * <font color=#7F9FBF>@param</font> server - implementation of service event listener 
+     */</font>
+    <font color=#7F0055>void</font> addEventListener(IService service, IEventListener listener);
+ 
+    <font color=#3F5FBF>/**
+     * Unsubscribe an event message listener for given service.
+     * <font color=#7F9FBF>@param</font> service - remote service proxy
+     * <font color=#7F9FBF>@param</font> server - implementation of service event listener 
+     */</font>
+    <font color=#7F0055>void</font> removeEventListener(IService service, IEventListener listener);
+ 
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> IPeer object representing local endpoint of communication channel.
+     */</font>
+    IPeer getLocalPeer();
+ 
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> IPeer object representing remote endpoint of communication channel.
+     */</font>
+    IPeer getRemotePeer();
+ 
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> collection of services available on local peer.
+     */</font>
+    Collection&lt;String> getLocalServices();
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> an object representing a service from local peer.
+     * Return null if the service is not available.
+     */</font>
+    IService getLocalService(String service_name);
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> an object representing a service from local peer.
+     * Service object should implement given interface.
+     * Return null if implementation of the interface is not available.
+     */</font>
+    &lt;V <font color=#7F0055>extends</font> IService> V getLocalService(Class&lt;V> service_interface);
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> collection of services available on remote peer.
+     */</font>
+    Collection&lt;String> getRemoteServices();
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> an object (proxy) representing a service from remote peer.
+     * Return null if the service is not available.
+     * Return an instance of GenericProxy if 'service_name' is not a standard TCF service.
+     */</font>
+    IService getRemoteService(String service_name);
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> an object (proxy) representing a service from remote peer,
+     * which implements given interface.
+     * Return null if implementation of the interface is not available.
+     */</font>
+    &lt;V <font color=#7F0055>extends</font> IService> V getRemoteService(Class&lt;V> service_interface);
+ 
+    <font color=#3F5FBF>/**
+     * Install a service proxy object on this channel.
+     * This method can be called only from channel open call-back.
+     * It allows a client to extends TCF by adding proxy objects for non-standard services.
+     * Client, wishing to become service proxy provider, should register itself
+     * using either Protocol.addChannelOpenListener() or IChannel.addChannelListener().
+     * It is not allowed to register more then one proxy for a given service interface.   
+     */</font>
+    &lt;V <font color=#7F0055>extends</font> IService&gt; <font color=#7F0055>void</font> setServiceProxy(Class&lt;V&gt; service_interface, IService service_proxy);
+
+    <font color=#3F5FBF>/**
+     * Close communication channel.
+     */</font>
+    <font color=#7F0055>void</font> close();
+ 
+    <font color=#3F5FBF>/**
+     * Close channel in case of communication error.
+     * <font color=#7F9FBF>@param error</font> - cause of channel termination
+     */</font>
+    <font color=#7F0055>void</font> terminate(Throwable error);
+    
+    <font color=#3F5FBF>/**
+     * Redirect this channel to given peer using this channel remote peer locator service as a proxy.
+     * <font color=#7F9FBF>@param peer_</font> - peer that will become new remote communication endpoint of this channel
+     */</font>
+    <font color=#7F0055>void</font> redirect(IPeer peer);
+}
+ 
+ 
+<font color=#3F5FBF>/**
+ * Object implemeting IToken interface is created by framework for every
+ * command sent over communication channel. It is used to match command to its
+ * results, and also can be used to cancel commands.
+ */</font>
+<font color=#7F0055>public</font> interface IToken {
+    
+    <font color=#3F5FBF>/**
+     * Try to cancel a command associated with given token. A command can be
+     * canceled by this method only if it was not transmitted yet to remote peer
+     * for execution. Successfully canceled command does not produce any result
+     * messages.
+     * 
+     * <font color=#7F9FBF>@return</font> true if successful.
+     */</font>
+    <font color=#7F0055>boolean</font> cancel();
+}
+
+</pre>
+
+<h1><a name='JSON'>Preferred Marshaling</a></h1>
+
+<p>TCF messages data format is service specific. Since services specifications are
+separate from protocol specification, a service designer can choose any data format that
+suits the service requirements best. However, to promote better compatibility and to
+simplify service design and implementation, we recommend to use <b>JSON</b> for data formatting.</p>
+ 
+<p><b>JSON</b> (pronounced like the
+English given name <i>Jason</i>), which stands for "<b>J</b>ava<b>S</b>cript <b>O</b>bject
+<b>N</b>otation", is a lightweight, text-based, language-independent computer data
+interchange format. <b>JSON</b> is a subset of the object literal notation of JavaScript
+but its use does not require JavaScript.</p>
+ 
+<p><b>JSON</b> represents data with the same basic types that programming languages
+use. <b>JSON</b>'s basic types are:</p>
+ 
+<ul type='disc'>
+    <li>Number (integer, real, or floating-point) 
+ 
+    <li>String (double-quoted with backslash escapement) 
+ 
+    <li>Boolean (<code>true</code> and <code>false</code>)
+ 
+    <li>Array (an ordered sequence of values) 
+ 
+    <li>Object (collection of key/value pairs) 
+ 
+    <li><code>null</code> 
+ </ul>
+ 
+<p>The structures used in most programming languages easily map directly onto JSON's
+structures, and back again.</p>
+ 
+<p>JSON maps data onto Unicode string. Then the string is mapped onto array of bytes
+using UTF-8 encoding.</p>
+ 
+<p>JSON specification:</p>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+<i>&lt;object&gt;</i>
+    &rArr; {}
+    &rArr; { <i>&lt;members&gt;</i> }
+ 
+<i>&lt;members&gt;</i>
+    &rArr; <i>&lt;string&gt;</i> : <i>&lt;value&gt;</i>
+    &rArr; <i>&lt;members&gt;</i> , <i>&lt;string&gt;</i> : <i>&lt;value&gt;</i>
+ 
+<i>&lt;array&gt;</i>
+    &rArr; []
+    &rArr; [ <i>&lt;elements&gt;</i> ]
+ 
+<i>&lt;elements&gt;</i>
+    &rArr; <i>&lt;value&gt;</i>
+    &rArr; <i>&lt;elements</i>&gt; , <i>&lt;value&gt;</i>
+ 
+<i>&lt;value&gt;</i>
+    &rArr; <i>&lt;string&gt;</i>
+    &rArr; <i>&lt;number&gt;</i>
+    &rArr; <i>&lt;object&gt;</i>
+    &rArr; <i>&lt;array&gt;</i>
+    &rArr; <i>&lt;boolean&gt;</i>
+    &rArr; null
+
+<i>&lt;boolean&gt;</i> 
+    &rArr; true
+    &rArr; false
+
+<i>&lt;string&gt;</i>
+    &rArr; ""
+    &rArr; " <i>&lt;chars&gt;</i> "
+ 
+<i>&lt;chars&gt;</i>
+    &rArr; <i>&lt;char&gt;</i>
+    &rArr; <i>&lt;chars&gt; &lt;char&gt;</i>
+
+<i>&lt;char</i>&gt;
+    &rArr; <i>&lt;any Unicode except " or \ or control&gt;</i>
+    &rArr; \"<i></i>
+    &rArr; \\<i></i>
+    &rArr; \/<i></i>
+    &rArr; \b<i></i>
+    &rArr; \f<i></i>
+    &rArr; \n<i></i>
+    &rArr; \r<i></i>
+    &rArr; \t<i></i>
+    &rArr; \u <i>&lt;four-hex-digits&gt;</i>
+
+<i>&lt;number</i>&gt;
+    &rArr; <i>&lt;int&gt;</i>
+    &rArr; &lt;<i>int&gt; &lt;fraction&gt;</i>
+    &rArr; &lt;<i>int&gt; &lt;exponent&gt;</i>
+    &rArr; &lt;<i>int&gt; &lt;fraction&gt; &lt;exponent&gt;</i>
+ 
+<i>&lt;int&gt;</i>
+    &rArr; <i>&lt;digit&gt;</i>
+    &rArr; &lt;<i>digit 1-9&gt; &lt;digits&gt;</i> 
+    &rArr; - &lt;<i>digit&gt;</i>
+    &rArr; - &lt;<i>digit 1-9&gt; &lt;digits</i>&gt;
+ 
+<i>&lt;fraction&gt;</i> 
+    &rArr; . <i>&lt;digits&gt;</i> 
+ 
+<i>&lt;exponent&gt;</i> 
+    &rArr; <i>&lt;e&gt;</i> <i>&lt;digits&gt;</i> 
+ 
+<i>&lt;digits&gt;</i> 
+    &rArr; <i>&lt;digit&gt;</i>
+    &rArr; &lt;<i>digits&gt;</i> &lt;<i>digit&gt;</i> 
+ 
+<i>&lt;e&gt;</i>
+    &rArr; e
+    &rArr; e+
+    &rArr; e-
+    &rArr; E
+    &rArr; E+
+    &rArr; E-
+
+</font></b></pre>
+
+<p>See <a href='http://www.json.org/'>www.json.org</a> for more details.</p>
+ 
+<h2><a name='JSONExamples'>Examples</a></h2>
+ 
+<p>This is a JSON array containing two objects:</p>
+ 
+<pre>
+   [
+       {
+          "Precision": "zip",
+          "Latitude":  37.7668,
+          "Longitude": -122.3959,
+          "City":      "SAN FRANCISCO",
+          "State":     "CA",
+          "Zip":       "94107",
+          "Country":   "US"
+       },
+       {
+          "Precision": "zip",
+          "Latitude":  37.371991,
+          "Longitude": -122.026020,
+          "City":      "SUNNYVALE",
+          "State":     "CA",
+          "Zip":       "94085",
+          "Country":   "US"
+       }
+   ]
+</pre>
+  
+<h1><a name='Locator'>Locator Service</a></h1>
+
+<p>Locator Service uses transport layer to search for peers and to collect data about
+peer's attributes and capabilities (services).  Discovery mechanism depends on transport
+protocol and is part of that protocol handler. Targets, known by other hosts, are
+added to local list of peers. <font color=red>Security? </font>Automatically discovered
+targets require no further configuration. Additional targets can be configured manually.</p>
+
+<p>All TCF peers must implement Locator service. The implementation is part of the framework itself.
+It is the only required service, all other services are optional and, formally, not part of the framework.</p>
+
+<h2><a name='LocatorPeer'>Peer Atributes</a></h2>
+
+<p><i>&lt;object: peer data&gt;</i> is collection of peer attributes. It should, at least, contain member
+<b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b>.
+It can also contain a number of components describing peer properties and capabilities.
+Predefined attributes are:</p>
+
+<ul>
+    <li><code><b><font face="Courier New" size=2 color=#333399>"ID" : <i>&lt;string&gt;</i></font></b></code>
+    - ID of the peer.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Name" : <i>&lt;string&gt;</i></font></b></code>
+    - human readable peer name.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"OSName" : <i>&lt;string&gt;</i></font></b></code>
+    - peer OS name, if applicable.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"TransportName" : <i>&lt;string&gt;</i></font></b></code>
+    - name of a trasport protocol to use to connect to this peer, for example: TCP.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Host" : <i>&lt;string&gt;</i></font></b></code>
+    - peer host name, if transport is TCP or UDP.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Aliases" : <i>&lt;string&gt;</i></font></b></code>
+    - peer host name aliases, if transport is TCP or UDP.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Addresses" : <i>&lt;string&gt;</i></font></b></code>
+    - peer IP addresses, if transport is TCP or UDP.
+
+    <li><code><b><font face="Courier New" size=2 color=#333399>"Port" : <i>&lt;string&gt;</i></font></b></code>
+    - peer port number, if transport is TCP or UDP.
+</ul>
+
+<p>Most clients dont need to know peer attributes other then ID and Name. Clients are expected to call IPeer.openChannel()
+method and let the framework to check peers attributes and create appropriate communication cahnnel that is best suited for
+communication with the peer. After a channel is established, a client can learn peer capabilities by looking
+at services it implements (use IChannel.getRemoteServices() method to get a map of services).</p>
+
+<h2><a name='LocatorCommands'>Locator Service Commands</a></h2>
+
+<h3><a name='LocatorCommandRedirect'>redirect</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Locator &bull; redirect &bull; <i>&lt;string: peer ID&gt;</i> &bull;
+</font></b></pre>
+
+<p>The command redirects the channel to become connected to given peer.
+Locator service starts acting as a proxy.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull; <i>&lt;error report&gt;</i> &bull;
+</font></b></pre>
+ 
+<h3><a name='LocatorCommandSync'>sync</a></h3>
+ 
+<pre><b><font face="Courier New" size=2 color=#333399>
+C &bull; <i>&lt;token&gt;</i> &bull; Locator &bull; sync &bull;
+</font></b></pre>
+
+<p>Sync command does nothing and simply returns back an empty result. The command is used for
+cross channel synchronization. Since commands are executed in order they were issued, by waiting
+for sync result a client makes sure that all commands, that were issued before sync, are fully processed.</p>
+
+<p>Reply:</p>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+R &bull; <i>&lt;token&gt;</i> &bull;
+</font></b></pre>
+ 
+<h2><a name='LocatorEvents'>Locator Service Events</a></h2>
+
+<pre><b><font face="Courier New" size=2 color=#333399>
+E &bull; Locator &bull; Hello &bull; <i>&lt;array: service names&gt;</i> &bull;
+E &bull; Locator &bull; peerAdded &bull; <i>&lt;object: peer data&gt;</i> &bull;
+E &bull; Locator &bull; peerChanged &bull; <i>&lt;object: peer data&gt;</i> &bull;
+E &bull; Locator &bull; peerRemoved &bull; <i>&lt;string: peer ID&gt;</i> &bull;
+</font></b></pre>
+
+<dl>
+    <dt><b>Hello</b>
+        <dd>is the first message sent by the framework after establishing a communication channel.
+        The message lets other side of the channel to know capabilities of this peer.
+        Message data consists of an array of service names that are provided by the peer.
+        Service names list is a complete and unambiguous declaration of peer's capabilities.
+        To avoid ambiguity, different services (even slightly different, like versions of same service)
+        must have different names. Framework delays all other communications between peers until exchange
+        of Hello messages is complete.
+    <dt><b>peerAdded</b>
+        <dd>is sent when the service discovers a new peer.
+    <dt><b>peerChanged</b>
+        <dd>is sent when peer attributes change.
+    <dt><b>peerRemoved</b>
+        <dd>is sent when the service deletes information about a peer.
+</dl>
+
+<h2><a name='LocatorAPI'>Locator Service API</a></h2>
+
+<pre>
+<font color=#3F5FBF>/**
+ * Base interface for all service interfaces. A client can get list of available services
+ * by calling IChannel.getLocalServices() and IChannel.getRemoteServices().
+ * 
+ * Remote services are represented by a proxy objects that implement service interfaces by
+ * translating method calls to TCF messages and sending them to a remote peer.
+ * When communication channel is open, TCF automatically creates proxies for standard services.
+ * TCF clients can provides addition proxies for non-standard services by calling IChannel.setServiceProxy(). 
+ */</font>
+<font color=#7F0055>public</font> interface IService {
+ 
+    <font color=#3F5FBF>/**
+     * Get unique name of this service.
+     */</font>
+    String getName();
+}
+ 
+<font color=#3F5FBF>/**
+ * Both hosts and targets are represented by objects
+ * implementing IPeer interface. A peer can act as host or
+ * target depending on services it implements.
+ * List of currently known peers can be retrieved by
+ * calling ILocator.getPeers
+ */</font>
+<font color=#7F0055>public interface</font> IPeer {
+    
+    <font color=#7F0055>static final</font> String
+        <i><font color=#0000C0>ATTR_ID</font></i> = <font color=#2A00FF>"ID"</font>,
+        <i><font color=#0000C0>ATTR_NAME</font></i> = <font color=#2A00FF>"Name"</font>,
+        <i><font color=#0000C0>ATTR_OS_NAME</font></i> = <font color=#2A00FF>"OSName"</font>,
+        <i><font color=#0000C0>ATTR_TRANSPORT_NAME</font></i> = <font color=#2A00FF>"TransportName"</font>,
+        <i><font color=#0000C0>ATTR_IP_HOST</font></i> = <font color=#2A00FF>"Host"</font>,
+        <i><font color=#0000C0>ATTR_IP_ALIASES</font></i> = <font color=#2A00FF>"Aliases"</font>,
+        <i><font color=#0000C0>ATTR_IP_ADDRESSES</font></i> = <font color=#2A00FF>"Addresses"</font>,
+        <i><font color=#0000C0>ATTR_IP_PORT</font></i> = <font color=#2A00FF>"Port"</font>;
+            
+    
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> map of peer attributes
+     */</font>
+    Map&lt;String, String&gt; getAttributes();
+ 
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> peer unique ID, same as getAttributes().get(ATTR_ID)
+     */</font>
+    String getID();
+ 
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> peer name, same as getAttributes().get(ATTR_NAME)
+     */</font>
+    String getName();
+ 
+    <font color=#3F5FBF>/**
+     * Same as getAttributes().get(ATTR_OS_NAME)
+     */</font>
+    String getOSName();
+ 
+    <font color=#3F5FBF>/**
+     * Same as getAttributes().get(ATTR_TRANSPORT_NAME)
+     */</font>
+    String getTransportName();
+ 
+    <font color=#3F5FBF>/**
+     * Open channel to communicate with this peer.
+     * Note: the channel is not fully open yet when this method returns.
+     * It's state is IChannel.STATE_OPENNING.
+     * Protocol.Listener will be called when the channel will be opened or closed.
+     */</font>
+    IChannel openChannel() <font color=#7F0055>throws</font> IOException;
+}
+ 
+<font color=#3F5FBF>/**
+ * ILocator service uses transport layer to search for peers and to collect data about
+ * peer's attributes and capabilities (services). Discovery mechanism depends on
+ * transport protocol and is part of that protocol handler. Targets, known by other
+ * hosts, are added to local list of peers.
+ * Automatically discovered targets require no further configuration. Additional targets
+ * can be configured manually.
+ * 
+ * Clients should use Protocol.getLocator() to obtain local instance of ILocator,
+ * then ILocator.getPeers() can be used to get of available peers (hosts and targets).
+ */</font>
+<font color=#7F0055>public interface</font> ILocator <font color=#7F0055>extends</font> IService {
+    
+    <font color=#7F0055>static final</font> String <i><font color=#0000C0>NAME</font></i> = <font color=#2A00FF>"Locator"</font>;
+ 
+    <font color=#3F5FBF>/**
+     * Auto-configuration command and response codes.
+     */</font>
+    <font color=#7F0055>static final int</font>
+        <i><font color=#0000C0>CONF_REQ_INFO</font></i> = 1,
+        <i><font color=#0000C0>CONF_PEER_INFO</font></i> = 2;
+
+    <font color=#3F5FBF>/**
+     * <font color=#7F9FBF>@return</font> Locator service name: "Locator"
+     */</font>
+    String getName();
+ 
+    <font color=#3F5FBF>/**
+     * Get map (ID -> IPeer) of available peers (hosts and targets).
+     * The method return cached (currently known to the framework) list of peers.
+     * The list is updated according to event received from transport layer
+     */</font>
+    Map&lt;String,IPeer&gt; getPeers();
+ 
+    <font color=#3F5FBF>/**
+     * Redirect this service channel to given peer using this service as a proxy.
+     */</font>
+    IToken redirect(String peer_id, DoneRedirect done);
+    
+    <font color=#7F0055>interface</font> DoneRedirect {
+        <font color=#7F0055>void</font> doneRedirect(IToken token, Exception error);
+    }
+ 
+    <font color=#3F5FBF>/**
+     * Call back after TCF messages sent to this target up to this moment are delivered.
+     * This method is intended for synchronization of messages
+     * across multiple channels.
+     * 
+     * Note: Cross channel synchronization can reduce performance and throughput.
+     * Most clients don't need channel synchronization and should not call this method. 
+     *  
+     * @param done will be executed by dispatch thread after communication 
+     * messages are delivered to corresponding targets.
+     * 
+     * This is internal API, TCF clients should use {@code org.eclipse.tm.tcf.protocol.Protocol}.
+     */</font>
+    IToken sync(DoneSync done);
+    
+    <font color=#7F0055>interface</font> DoneSync {
+        <font color=#7F0055>void</font> doneSync(IToken token);
+    }
+
+    <font color=#3F5FBF>/**
+     * Add a listener for locator service events.
+     */</font>
+    <font color=#7F0055>void</font> addListener(Listener listener);
+ 
+    <font color=#3F5FBF>/**
+     * Remove a listener for locator service events.
+     */</font>
+    <font color=#7F0055>void</font> removeListener(Listener listener);
+ 
+    <font color=#7F0055>interface</font> Listener {
+        <font color=#7F0055>void</font> peerAdded(IPeer peer);
+ 
+        <font color=#7F0055>void</font> peerRemoved(IPeer peer);
+ 
+        <font color=#7F0055>void</font> peerChanged(IPeer peer);
+    }
+}
+</pre>
+
+</body>
+</html>
+ 
Binary file dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_Launch_Dialog.jpg has changed
Binary file dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_RSE_Files.jpg has changed
Binary file dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/TCF_RSE_Processes.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf.docs/index.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+    <title>Target Communication Framework</title>
+</head>
+<body>
+<h1>Target Communication Framework </h1>
+
+<p>Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. Made available under the EPL v1.0
+(Agent portion made available under your choice of EPL v1.0 or EDL v1.0 dual-license).
+<p>Direct comments, questions to the <a href="mailto:dsdp-tcf-dev@eclipse.org">dsdp-tcf-dev@eclipse.org</a> mailing list
+
+<h2>Available Documentation</h2>
+
+<table border=1 cellpadding=8>
+    <tr>
+        <td><a href='TCF Project.html'>TCF Project Overview</a>
+        <td width=500>TCF project goals and results
+    <tr>
+        <td><a href='TCF Getting Started.html'>TCF: Getting Started</a>
+        <td width=500>Getting started with TCF - creating Eclipse workspace, building agent, making a first connection
+    <tr>
+        <td><a href='TCF Specification.html'>TCF Specifications</a>
+        <td width=500>Design goals, requirements and format of TCF communication protocol,
+        framework API and software design considerations
+    <tr>
+        <td><a href='TCF Services.html'>TCF Services Definitions</a>
+        <td width=500>TCF communication model is based on the idea of services.
+        A service is a group of related commands, events and semantics.
+        New services are expected to be defined by developers of tools and target agents.
+        To achieve certain level of compatibility of tools/targets TCF inclides definitions
+        of common services
+    <tr>
+        <td><a href='TCF Context Identifier Explanation.html'>TCF Context Identifier Explanation</a>
+        <td width=500>Most if not all TCF services functions need some way to identify what entity e.g. process,
+        thread, task, device on JTAG scan chain, etc they should operate on.
+        To do this TCF uses a context identifier (aka ContextId). This document is attempting to explain how
+        ContextIds are intended to be used
+    <tr>
+        <td><a href='TCF Linux Agent Prototype.html'>TCF Agent Prototype</a>
+        <td width=500>
+        Brief description of the TCF target agent prototype implementation
+    <tr>
+        <td>
+        <a href='TCF Agent Porting Guide.html'>TCF Agent Porting Guide</a>
+        <td width='500'>A guide for porting and customizing TCF agent code
+</table>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.classpath	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<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 combineaccessrules="false" exported="true" kind="src" path="/org.eclipse.tm.tcf.core"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.cvsignore	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,1 @@
+bin
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.project	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.tm.tcf</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.settings/org.eclipse.jdt.core.prefs	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,271 @@
+#Thu Apr 30 00:11:15 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/.settings/org.eclipse.jdt.ui.prefs	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,4 @@
+#Mon Jan 07 15:38:38 PST 2008
+eclipse.preferences.version=1
+formatter_profile=_Java STD
+formatter_settings_version=11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/META-INF/MANIFEST.MF	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.tcf;singleton:=true
+Bundle-Version: 0.3.0.qualifier
+Bundle-Activator: org.eclipse.tm.tcf.Activator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Eclipse-LazyStart: true
+Eclipse-ExtensibleAPI: true
+Export-Package: org.eclipse.tm.tcf.extensions,
+ org.eclipse.tm.tcf.ssl;version="0.2.0"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/about.html	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>January 10, 2008</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/build.properties	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,11 @@
+source.. = src/
+output.. = bin/
+extra.. = ../org.eclipse.tm.tcf.core/bin
+bin.includes = META-INF/,\
+               .,\
+               about.html,\
+               plugin.properties,\
+               plugin.xml
+src.includes = about.html,\
+               schema/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/plugin.properties	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#  
+# Contributors:
+#     Wind River Systems - initial implementation
+###############################################################################
+pluginName = Target Communication Framework (TCF) (Incubation)
+providerName = Eclipse.org
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/plugin.xml	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+   <extension-point id="startup" name="TCF Startup" schema="schema/startup.exsd"/>
+   <extension-point id="serviceProviders" name="TCF Service Providers" schema="schema/serviceProviders.exsd"/>
+
+</plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/schema/serviceProviders.exsd	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,114 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.tcf" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.tm.tcf" id="serviceProviders" name="TCF Service Providers"/>
+      </appInfo>
+      <documentation>
+         This extension point is used to allow the contribution of new TCF service providers.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="serviceProvider" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="serviceProvider">
+      <annotation>
+         <documentation>
+            Declares a new service provider extension.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The unique id of the service provider.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The fully qualified name of the service provider class. Must implement &lt;samp&gt;org.eclipse.tm.tcf.protocol.IServiceProvider&lt;/samp&gt;
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.tm.tcf.protocol.IServiceProvider"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         0.3.0
+      </documentation>
+   </annotation>
+
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiinfo"/>
+      </appInfo>
+      <documentation>
+         Plug-ins that want to extend this extension point, the referenced class must implement the  &lt;samp&gt;org.eclipse.tm.tcf.protocol.IServiceProvider&lt;/samp&gt; interface.
+      </documentation>
+   </annotation>
+
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2009 Wind River Systems, Inc. and others.
+
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+
+Contributors:
+     Wind River Systems - initial API and implementation
+      </documentation>
+   </annotation>
+
+</schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/schema/startup.exsd	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,73 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.tcf">
+<annotation>
+   <appInfo>
+      <meta.schema plugin="org.eclipse.tm.tcf" id="startup" name="TCF Startup"/>
+   </appInfo>
+   <documentation>
+      This extension point is used to register plugins
+      that want to be activated on TCF startup.
+      Once the TCF is started, registered plugins will be activated. 
+   </documentation>
+
+</annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="class" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="class">
+      <complexType>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+               Class will be loaded and initialized during TCF statup   
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+      </documentation>
+   </annotation>
+
+</schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/Activator.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.tcf.internal.extensions.TcfServiceProvidersExtensionPointManager;
+import org.eclipse.tm.tcf.core.ChannelTCP;
+import org.eclipse.tm.tcf.protocol.ILogger;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.ssl.TCFSecurityManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+    public static final String PLUGIN_ID = "org.eclipse.tm.tcf"; //$NON-NLS-1$
+
+    private static Activator plugin;
+    private static boolean debug;
+    private static final EventQueue queue = new EventQueue();
+    private static final BundleListener bundle_listener = new BundleListener() {
+        private boolean started = false;
+        public void bundleChanged(BundleEvent event) {
+            if (plugin != null && !started && event.getBundle() == plugin.getBundle() &&
+                    plugin.getBundle().getState() == Bundle.ACTIVE) {
+                queue.start();
+                started = true;
+            }
+        }
+    };
+
+    /**
+     * Constructor.
+     */
+    public Activator() {
+        plugin = this;
+    }
+
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static Activator getDefault() {
+            return plugin;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        debug = Platform.inDebugMode();
+        ChannelTCP.setSSLContext(TCFSecurityManager.createSSLContext());
+        Protocol.setLogger(new ILogger() {
+
+            public void log(String msg, Throwable x) {
+                if (debug) {
+                    System.err.println(msg);
+                    if (x != null) x.printStackTrace();
+                }
+                if (plugin != null && getLog() != null) {
+                    getLog().log(new Status(IStatus.ERROR,
+                            getBundle().getSymbolicName(), IStatus.OK, msg, x));
+                }
+            }
+        });
+        Protocol.setEventQueue(queue);
+        Protocol.invokeLater(new Runnable() {
+            public void run() {
+                runTCFStartup();
+            }
+        });
+        context.addBundleListener(bundle_listener);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        context.removeBundleListener(bundle_listener);
+        queue.shutdown();
+        plugin = null;
+        super.stop(context);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void runTCFStartup() {
+        try {
+            IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, "startup"); //$NON-NLS-1$
+            IExtension[] extensions = point.getExtensions();
+            for (int i = 0; i < extensions.length; i++) {
+                try {
+                    Bundle bundle = Platform.getBundle(extensions[i].getNamespaceIdentifier());
+                    bundle.start(Bundle.START_TRANSIENT);
+                    IConfigurationElement[] e = extensions[i].getConfigurationElements();
+                    for (int j = 0; j < e.length; j++) {
+                        String nm = e[j].getName();
+                        if (nm.equals("class")) { //$NON-NLS-1$
+                            Class c = bundle.loadClass(e[j].getAttribute("name")); //$NON-NLS-1$
+                            Class.forName(c.getName(), true, c.getClassLoader());
+                        }
+                    }
+                }
+                catch (Throwable x) {
+                    Protocol.log("TCF startup error", x); //$NON-NLS-1$
+                }
+            }
+        }
+        catch (Exception x) {
+            Protocol.log("TCF startup error", x); //$NON-NLS-1$
+        }
+
+        // Register service providers contributed via Eclipse extension point
+        TcfServiceProvidersExtensionPointManager.getInstance().registerServiceProviders();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf;
+
+import java.util.LinkedList;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.tm.tcf.protocol.IEventQueue;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+
+/**
+ * Implementation of Target Communication Framework event queue.
+ * This implementation is intended for Eclipse environment.
+ */
+class EventQueue implements IEventQueue, Runnable {
+
+    private final LinkedList<Runnable> queue = new LinkedList<Runnable>();
+    private final Thread thread;
+    private boolean waiting;
+    private boolean shutdown;
+    private int job_cnt;
+
+    EventQueue() {
+        thread = new Thread(this);
+        thread.setDaemon(true);
+        thread.setName("TCF Event Dispatch"); //$NON-NLS-1$
+        // Need to monitor jobs to detect congestion
+        Job.getJobManager().addJobChangeListener(new IJobChangeListener() {
+
+            public void aboutToRun(IJobChangeEvent event) {
+                job_cnt++;
+            }
+
+            public void awake(IJobChangeEvent event) {
+            }
+
+            public void done(IJobChangeEvent event) {
+                job_cnt--;
+                if (Job.getJobManager().isIdle()) job_cnt = 0;
+            }
+
+            public void running(IJobChangeEvent event) {
+            }
+
+            public void scheduled(IJobChangeEvent event) {
+            }
+
+            public void sleeping(IJobChangeEvent event) {
+            }
+        });
+    }
+
+    void start() {
+        thread.start();
+    }
+
+    void shutdown() {
+        try {
+            synchronized (this) {
+                shutdown = true;
+                if (waiting) {
+                    waiting = false;
+                    notifyAll();
+                }
+            }
+            thread.join();
+        }
+        catch (Exception e) {
+            Protocol.log("Failed to shutdown TCF event dispatch thread", e); //$NON-NLS-1$
+        }
+    }
+
+    private void error(Throwable x) {
+        Protocol.log("Unhandled excetion in TCF event dispatch", x); //$NON-NLS-1$
+    }
+
+    public void run() {
+        for (;;) {
+            try {
+                Runnable r = null;
+                synchronized (this) {
+                    while (queue.isEmpty()) {
+                        if (shutdown) return;
+                        waiting = true;
+                        wait();
+                    }
+                    r = queue.removeFirst();
+                }
+                r.run();
+            }
+            catch (Throwable x) {
+                error(x);
+            }
+        }
+    }
+
+    public synchronized void invokeLater(final Runnable r) {
+        assert r != null;
+        if (shutdown) throw new IllegalStateException("TCF event dispatch is shutdown"); //$NON-NLS-1$
+        queue.add(r);
+        if (waiting) {
+            waiting = false;
+            notifyAll();
+        }
+    }
+
+    public boolean isDispatchThread() {
+        return Thread.currentThread() == thread;
+    }
+
+    public synchronized int getCongestion() {
+        int l0 = job_cnt / 10 - 100;
+        int l1 = queue.size() / 10 - 100;
+        if (l1 > l0) l0 = l1;
+        if (l0 > 100) l0 = 100;
+        return l0;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfAbstractExtensionPointManager.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.extensions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.tcf.Activator;
+import org.eclipse.tm.tcf.internal.nls.TcfPluginMessages;
+
+
+/**
+ * Abstract extension point manager base implementation.
+ */
+public abstract class TcfAbstractExtensionPointManager<V> {
+    // Flag to mark the extension point manager initialized (extensions loaded).
+    private boolean fInitialized = false;
+    // The map of loaded extension listed by their unique ids
+    private Map<String, TcfExtensionProxy<V>> fExtensions = new LinkedHashMap<String, TcfExtensionProxy<V>>();
+    // The extension point comparator
+    private TcfExtensionPointComparator fComparator = null;
+
+    /**
+     * Constructor.
+     */
+    public TcfAbstractExtensionPointManager() {
+    }
+
+    /**
+     * Returns if or if not the service provider extension point manager
+     * got initialized. Initialized means that the manager read the
+     * contributitions for the managed extension point.
+     *
+     * @return <code>True</code> if already initialized, <code>false</code> otherwise.
+     */
+    protected boolean isInitialized() {
+        return fInitialized;
+    }
+
+    /**
+     * Sets if or if not the service provider extension point manager
+     * is initialized. Initialized means that the manager has read
+     * the contributitions for the managed extension point.
+     *
+     * @return <code>True</code> to set the extension point manager is initialized, <code>false</code> otherwise.
+     */
+    protected void setInitialized(boolean initialized) {
+        fInitialized = initialized;
+    }
+
+    /**
+     * Returns the map of managed extensions. If not loaded before,
+     * this methods trigger the loading of the extensions to the managed
+     * extension point.
+     *
+     * @return The map of contributables.
+     */
+    protected Map<String, TcfExtensionProxy<V>> getExtensions() {
+            if (!isInitialized()) { loadExtensions(); setInitialized(true); }
+            return fExtensions;
+    }
+
+    /**
+     * Returns the extensions of the specified extension point sorted.
+     * For the order of the extensions, see {@link WRLaunchExtensionPointComparator}.
+     *
+     * @param point The extension point. Must be not <code>null</code>.
+     * @return The extensions in sorted order or an empty array if the extension point has no extensions.
+     */
+    protected IExtension[] getExtensionsSorted(IExtensionPoint point) {
+        assert point != null;
+
+        List<IExtension> extensions = new ArrayList<IExtension>(Arrays.asList(point.getExtensions()));
+        if (extensions.size() > 0) {
+            Collections.sort(extensions, getExtensionPointComparator());
+        }
+
+        return extensions.toArray(new IExtension[extensions.size()]);
+    }
+
+    /**
+     * Returns the extension point comparator instance. If not available,
+     * {@link #doCreateExtensionPointComparator()} is called to create a new instance.
+     *
+     * @return The extension point comparator or <code>null</code> if the instance creation fails.
+     */
+    protected final TcfExtensionPointComparator getExtensionPointComparator() {
+        if (fComparator == null) {
+            fComparator = doCreateExtensionPointComparator();
+        }
+        return fComparator;
+    }
+
+    /**
+     * Creates a new extension point comparator instance.
+     *
+     * @return The extension point comparator instance. Must never be <code>null</code>.
+     */
+    protected TcfExtensionPointComparator doCreateExtensionPointComparator() {
+        return new TcfExtensionPointComparator();
+    }
+
+    /**
+     * Returns the extension point id to read. The method
+     * must return never <code>null</code>.
+     *
+     * @return The extension point id.
+     */
+    protected abstract String getExtensionPointId();
+
+    /**
+     * Returns the configuration element name. The method
+     * must return never <code>null</code>.
+     *
+     * @return The configuration element name.
+     */
+    protected abstract String getConfigurationElementName();
+
+    /**
+     * Creates the extension proxy instance.
+     *
+     * @param element The configuration element of the extension. Must be not <code>null</code>.
+     * @return The extension proxy instance.
+     *
+     * @throws CoreException If the extension proxy instanciation failed.
+     */
+    protected TcfExtensionProxy<V> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+        assert element != null;
+        return new TcfExtensionProxy<V>(element);
+    }
+
+    /**
+     * Loads the extensions for the managed extenions point.
+     */
+    protected void loadExtensions() {
+        // If already initialized, this method will do nothing.
+        if (isInitialized()) return;
+
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+        IExtensionPoint point = registry.getExtensionPoint(getExtensionPointId());
+        if (point != null) {
+            IExtension[] extensions = getExtensionsSorted(point);
+            for (IExtension extension : extensions) {
+                IConfigurationElement[] elements = extension.getConfigurationElements();
+                for (IConfigurationElement element : elements) {
+                    if (getConfigurationElementName().equals(element.getName())) {
+                        try {
+                            TcfExtensionProxy<V> candidate = doCreateExtensionProxy(element);
+                            if (candidate.getId() != null) {
+                                // If no contributable with this id had been registered before, register now.
+                                if (!fExtensions.containsKey(candidate.getId())) {
+                                    fExtensions.put(candidate.getId(), candidate);
+                                }
+                                else {
+                                    throw new CoreException(new Status(IStatus.ERROR,
+                                            Activator.PLUGIN_ID,
+                                            0,
+                                            NLS.bind(TcfPluginMessages.Extension_error_duplicateExtension, candidate.getId(), element.getContributor().getName()),
+                                            null));
+                                }
+                            } else {
+                                throw new CoreException(new Status(IStatus.ERROR,
+                                        Activator.PLUGIN_ID,
+                                        0,
+                                        NLS.bind(TcfPluginMessages.Extension_error_missingRequiredAttribute, "id", element.getAttribute("label")), //$NON-NLS-1$ //$NON-NLS-2$
+                                        null));
+                            }
+                        } catch (CoreException e) {
+                            IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+                                                        NLS.bind(TcfPluginMessages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()),
+                                                        e);
+                            Activator.getDefault().getLog().log(status);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionPointComparator.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.extensions;
+
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.IExtension;
+
+/**
+ * TCF extension point comparator. Used to asure that extension are
+ * always read in the same order.
+ * <p>
+ * The order of the extensions is defined as following:<br>
+ * <ul><li>Extensions contributed by the TCF core plug-ins (<code>org.eclipse.tm.tcf.*</code>)
+ *         in ascending alphabetic order and</li>
+ *     <li>Extensions contributed by any other plug-in in ascending alphabetic order.</li>
+ *     <li>Extensions contributed by the same plug-in in ascending alphabetic order by the
+ *         extensions unique id</li>
+ * </ul>
+ */
+public class TcfExtensionPointComparator implements Comparator<IExtension> {
+    private final static String TCF_PLUGIN_PATTERN = "org.eclipse.tm.tcf.*"; //$NON-NLS-1$
+
+    /* (non-Javadoc)
+     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+     */
+    public int compare(IExtension o1, IExtension o2) {
+        // We ignore any comparisation with null and
+        if (o1 == null || o2 == null) return 0;
+        // Check if it is the exact same element
+        if (o1 == o2) return 0;
+
+        // The extensions are compared by the unique id of the contributing plugin first
+        String contributor1 = o1.getContributor().getName();
+        String contributor2 = o2.getContributor().getName();
+
+        // Contributions from TCF core plugins comes before 3rdParty Plugins
+        if (contributor1.startsWith(TCF_PLUGIN_PATTERN) && !contributor2.startsWith(TCF_PLUGIN_PATTERN))
+            return -1;
+        if (!contributor1.startsWith(TCF_PLUGIN_PATTERN) && contributor2.startsWith(TCF_PLUGIN_PATTERN))
+            return 1;
+        if (contributor1.startsWith(TCF_PLUGIN_PATTERN) && contributor2.startsWith(TCF_PLUGIN_PATTERN)) {
+            int value = contributor1.compareTo(contributor2);
+            // Within the same plugins, the extension are sorted by thier unique id (if available)
+            if (value == 0 && o1.getUniqueIdentifier() != null && o2.getUniqueIdentifier() != null)
+                return o1.getUniqueIdentifier().compareTo(o2.getUniqueIdentifier());
+            // Otherwise, just return the comparisation result from the contributors
+            return value;
+        }
+
+        // Contributions from all other plugins are sorted alphabetical
+        int value = contributor1.compareTo(contributor2);
+        // Within the same plugins, the extension are sorted by thier unique id (if available)
+        if (value == 0 && o1.getUniqueIdentifier() != null && o2.getUniqueIdentifier() != null)
+            return o1.getUniqueIdentifier().compareTo(o2.getUniqueIdentifier());
+        // Otherwise, just return the comparisation result from the contributors
+        return value;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/extensions/TcfExtensionProxy.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.extensions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.tcf.Activator;
+import org.eclipse.tm.tcf.internal.nls.TcfPluginMessages;
+
+/**
+ * TCF extension proxy implementation. The use of the proxy asures the
+ * lazy plug-in activation policy for the contributing plug-in.
+ */
+public class TcfExtensionProxy<V> {
+    // The extension instance. Create on first access
+    private V fInstance;
+    // The configuration element
+    private final IConfigurationElement fElement;
+    // The unique id of the extension.
+    private String fId;
+
+    /**
+     * Constructor.
+     *
+     * @param element The configuration element. Must be not <code>null</code>.
+     *
+     * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
+     */
+    public TcfExtensionProxy(IConfigurationElement element) throws CoreException {
+        assert element != null;
+        fElement = element;
+
+        // The <id> attribute is mandatory.
+        fId = element.getAttribute("id"); //$NON-NLS-1$
+        if (fId == null || fId.trim().length() == 0) {
+            throw new CoreException(new Status(IStatus.ERROR,
+                    Activator.PLUGIN_ID,
+                    0,
+                    NLS.bind(TcfPluginMessages.Extension_error_missingRequiredAttribute, "id", element.getContributor().getName()), //$NON-NLS-1$
+                    null));
+        }
+
+        fInstance = null;
+    }
+
+    /**
+     * Returns the extensions unique id.
+     *
+     * @return The unique id.
+     */
+    public String getId() {
+        return fId;
+    }
+
+    /**
+     * Returns the configuration element for this extension.
+     *
+     * @return The configuration element.
+     */
+    protected IConfigurationElement getConfigurationElement() {
+        return fElement;
+    }
+
+    /**
+     * Returns the extension class instance. The contributing
+     * plug-in will be activated if not yet activated anyway.
+     *
+     * @return The extension class instance. Might be <code>null</code> if the instanciation fails.
+     */
+    @SuppressWarnings("unchecked")
+    public V getInstance() {
+        if (fInstance == null) {
+            IConfigurationElement element = getConfigurationElement();
+            assert element != null;
+            if (element != null && element.getAttribute("class") != null) { //$NON-NLS-1$
+                try {
+                    fInstance = (V)element.createExecutableExtension("class"); //$NON-NLS-1$
+                } catch (Exception e) {
+                    // Possible exceptions: CoreException, ClassCastException.
+                    IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+                            NLS.bind(TcfPluginMessages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()),
+                            e);
+                    Activator.getDefault().getLog().log(status);
+                }
+            }
+        }
+        return fInstance;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        // Proxies are equal if they have encapsulate an element
+        // with the same unique id
+        if (obj instanceof TcfExtensionProxy<?>) {
+            return getId().equals(((TcfExtensionProxy<?>)obj).getId());
+        }
+        return super.equals(obj);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        // The hash code of a proxy is the one from the id
+        return getId().hashCode();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/extensions/TcfServiceProvidersExtensionPointManager.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.internal.extensions;
+
+import java.util.Map;
+
+import org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager;
+import org.eclipse.tm.tcf.extensions.TcfExtensionProxy;
+import org.eclipse.tm.tcf.protocol.IServiceProvider;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+/**
+ * Extension point manager implementation for "org.eclipse.tm.tcf.serviceProviders".
+ */
+public class TcfServiceProvidersExtensionPointManager extends TcfAbstractExtensionPointManager<IServiceProvider> {
+    /*
+     * Thread save singleton instance creation.
+     */
+    private static class LazyInstanceHolder {
+        public static TcfServiceProvidersExtensionPointManager fInstance = new TcfServiceProvidersExtensionPointManager();
+    }
+
+    /**
+     * Returns the singleton instance for the manager.
+     */
+    public static TcfServiceProvidersExtensionPointManager getInstance() {
+        return LazyInstanceHolder.fInstance;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager#getExtensionPointId()
+     */
+    @Override
+    protected String getExtensionPointId() {
+        return "org.eclipse.tm.tcf.serviceProviders"; //$NON-NLS-1$
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.tm.tcf.extensions.TcfAbstractExtensionPointManager#getConfigurationElementName()
+     */
+    @Override
+    protected String getConfigurationElementName() {
+        return "serviceProvider"; //$NON-NLS-1$
+    }
+
+    /**
+     * Register the contributed service provider extensions with the framework.
+     */
+    public void registerServiceProviders() {
+        // Load the extensions
+        Map<String, TcfExtensionProxy<IServiceProvider>> extensions = getExtensions();
+        // Loop the extensions and get the service provider instance.
+        // This will activate the contributing plugin.
+        for (TcfExtensionProxy<IServiceProvider> proxy : extensions.values()) {
+            IServiceProvider provider = proxy.getInstance();
+            if (provider != null) Protocol.addServiceProvider(provider);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.internal.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * TCF plugin externalized strings management.
+ */
+public class TcfPluginMessages extends NLS {
+
+    // The plug-in resouce bundle name
+    private static final String BUNDLE_NAME = "org.eclipse.tm.tcf.internal.tcf.TcfPluginMessages"; //$NON-NLS-1$
+
+    /**
+     * Static constructor.
+     */
+    static {
+        // Load message values from bundle file
+        NLS.initializeMessages(BUNDLE_NAME, TcfPluginMessages.class);
+    }
+
+    // **** Declare externalized string id's down here *****
+
+    public static String Extension_error_missingRequiredAttribute;
+    public static String Extension_error_duplicateExtension;
+    public static String Extension_error_invalidExtensionPoint;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/internal/nls/TcfPluginMessages.properties	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,8 @@
+#
+# org.eclipse.tm.tcf
+# Externalized Strings.
+#
+
+Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"!
+Extension_error_duplicateExtension=Duplicate extension with id ''{0}''. Ignoring duplicated contribution from contributor ''{1}''!
+Extension_error_invalidExtensionPoint=Failed to instanciate the executable extension from extension point ''{0}''.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsdp/tm/tcf_0_3_x/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/ssl/TCFSecurityManager.java	Mon Aug 17 16:02:00 2009 -0500
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution, and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors:
+ *     Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.tcf.ssl;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.Socket;
+import java.security.KeyFactory;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.eclipse.tm.tcf.Activator;
+import org.eclipse.tm.tcf.core.Base64;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+
+/**
+ * This class implements keys and certificates management for secure TCF channels.   
+ */
+public class TCFSecurityManager {
+    
+    public static File getCertificatesDirectory() {
+        File certs = Activator.getDefault().getStateLocation().append("certificates").toFile(); //$NON-NLS-1$
+        if (!certs.exists()) certs.mkdirs();
+        return certs;
+    }
+
+    public static SSLContext createSSLContext() {
+        try {
+            final File certs = getCertificatesDirectory();
+            if (!certs.exists()) certs.mkdirs();
+            final CertificateFactory cf = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
+            SSLContext context = SSLContext.getInstance("TLS"); //$NON-NLS-1$
+            
+            X509ExtendedKeyManager km = new X509ExtendedKeyManager() {
+
+                public X509Certificate[] getCertificateChain(String alias) {
+                    File f = new File(certs, "Local.cert"); //$NON-NLS-1$
+                    try {
+                        InputStream inp = new BufferedInputStream(new FileInputStream(f));
+                        X509Certificate cert = (X509Certificate)cf.generateCertificate(inp);
+                        inp.close();
+                        return new X509Certificate[] { cert };
+                    }
+                    catch (Exception x) {
+                        Protocol.log("Cannot read certificate: " + f, x); //$NON-NLS-1$
+                        return null;
+                    }
+                }
+                
+                public PrivateKey getPrivateKey(String alias) {
+                    File f = new File(certs, "Local.priv"); //$NON-NLS-1$
+                    try {
+                        BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "ASCII")); //$NON-NLS-1$
+                        StringBuffer bf = new StringBuffer();
+                        boolean app = false;
+                        for (;;) {
+                            String s = r.readLine();
+                            if (s == null) new Exception("Invalid format"); //$NON-NLS-1$
+                            else if (s.indexOf("-----BEGIN ") == 0) app = true; //$NON-NLS-1$
+                            else if (s.indexOf("-----END ") == 0) break; //$NON-NLS-1$
+                            else if (app) bf.append(s); 
+                        }
+                        r.close();
+                        KeyFactory kf = KeyFactory.getInstance("RSA"); //$NON-NLS-1$
+                        byte[] bytes = Base64.toByteArray(bf.toString().toCharArray());
+                        return kf.generatePrivate(new PKCS8EncodedKeySpec(bytes));
+                    }
+                    catch (Exception x) {
+                        Protocol.log("Cannot read private key: " + f, x); //$NON-NLS-1$
+                        return null;
+                    }
+                }
+                
+                public String[] getClientAliases(String keyType, Principal[] issuers) {
+                    return new String[] { "TCF" }; //$NON-NLS-1$
+                }
+                
+                public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+                    return "TCF"; //$NON-NLS-1$
+                }
+                
+                public String[] getServerAliases(String keyType, Principal[] issuers) {
+                    return new String[] { "TCF" }; //$NON-NLS-1$
+                }
+                
+                public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+                    return "TCF"; //$NON-NLS-1$
+                }
+            };
+            
+            X509TrustManager tm = new X509TrustManager() {
+                
+                public void checkClientTrusted(X509Certificate[] chain, String auth_type) throws CertificateException {
+                    if ("RSA".equals(auth_type) && chain != null && chain.length == 1) { //$NON-NLS-1$
+                        for (X509Certificate cert : getAcceptedIssuers()) {
+                            if (cert.equals(chain[0])) return;
+                        }
+                    }
+                    throw new CertificateException("Client certificate validation failed"); //$NON-NLS-1$
+                }
+                
+                public void checkServerTrusted(X509Certificate[] chain, String auth_type) throws CertificateException {
+                    if ("RSA".equals(auth_type) && chain != null && chain.length == 1) { //$NON-NLS-1$
+                        for (X509Certificate cert : getAcceptedIssuers()) {
+                            if (cert.equals(chain[0])) return;
+                        }
+                    }
+                    throw new CertificateException("Server certificate validation failed"); //$NON-NLS-1$
+                }
+                
+                public X509Certificate[] getAcceptedIssuers() {
+                    ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
+                    for (String fnm : certs.list()) {
+                        if (!fnm.endsWith(".cert")) continue; //$NON-NLS-1$
+                        try {
+                            InputStream inp = new BufferedInputStream(new FileInputStream(new File(certs, fnm)));
+                            X509Certificate cert = (X509Certificate)cf.generateCertificate(inp);
+                            inp.close();
+                            list.add(cert);
+                        }
+                        catch (Throwable x) {
+                            Protocol.log("Cannot load certificate: " + fnm, x); //$NON-NLS-1$
+                        }
+                    }
+                    return list.toArray(new X509Certificate[list.size()]);
+                }
+            };
+            
+            context.init(new KeyManager[] { km }, new TrustManager[] { tm }, null);
+            return context;
+        }
+        catch (Throwable x) {
+            Protocol.log("Cannot initialize SSL context", x); //$NON-NLS-1$
+            return null;
+        }
+    }
+}