Merge avec la branche xmpp pour obtenir le basculement des conversations
authorDa Risk <darisk972@gmail.com>
Fri, 29 May 2009 20:34:30 +0200
changeset 224 d8e2cb1eb895
parent 215 5db64229be69 (diff)
parent 223 bb656974bab1 (current diff)
child 225 cb15bad7d9ca
Merge avec la branche xmpp pour obtenir le basculement des conversations
AndroidManifest.xml
res/values/strings.xml
src/com/beem/project/beem/service/BeemChatManager.java
src/com/beem/project/beem/service/ChatAdapter.java
src/com/beem/project/beem/service/Contact.java
src/com/beem/project/beem/service/Message.java
src/com/beem/project/beem/ui/ContactDialog.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/SendIM.java
src/com/beem/project/beem/ui/Subscription.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.classpath	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="lib" path="libs/smack.jar"/>
+	<classpathentry kind="lib" path="libs/smackx-debug.jar"/>
+	<classpathentry kind="lib" path="libs/smackx-jingle.jar"/>
+	<classpathentry kind="lib" path="libs/smackx.jar"/>
+	<classpathentry kind="lib" path="libs/jlibrtp-0.2.2.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.settings/org.eclipse.jdt.core.prefs	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,337 @@
+#Tue May 26 10:33:43 CEST 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
+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.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+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.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=ignore
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=true
+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=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+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=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=true
+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=100
+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=4
+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=do not 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=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not 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=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+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=mixed
+org.eclipse.jdt.core.formatter.tabulation.size=8
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true
+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/.settings/org.eclipse.jdt.ui.prefs	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,109 @@
+#Tue May 26 10:35:42 CEST 2009
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=true
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_beem
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_beem
+formatter_settings_version=11
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=true
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.settings/org.eclipse.ltk.core.refactoring.prefs	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,3 @@
+#Tue May 26 10:03:53 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
--- a/AndroidManifest.xml	Sat May 23 20:59:27 2009 +0200
+++ b/AndroidManifest.xml	Fri May 29 20:34:30 2009 +0200
@@ -3,8 +3,9 @@
 	package="com.beem.project.beem" android:versionCode="1"
 	android:versionName="1.0">
 	<application android:label="@string/app_name" android:name="BeemApplication"
-		android:icon="@drawable/signal">
-		<activity android:name=".ui.ContactList" android:label="@string/app_name">
+		android:icon="@drawable/signal"
+		android:theme="@style/Theme.BEEM.Default">
+		<activity android:name=".ui.Login" android:label="@string/app_name">
 			<intent-filter>
 				<action android:name="android.intent.action.MAIN" />
 				<category android:name="android.intent.category.LAUNCHER" />
@@ -18,6 +19,12 @@
 		<activity android:name=".ui.AccountCreation" android:label="@string/app_name" />
 		<activity android:name=".ui.AddContact" android:label="@string/app_name" />
 		<activity android:name=".ui.Subscription" android:label="@string/app_name" />
+        <activity android:name=".ui.EditSettings" android:label="@string/edit_settings_name">
+        </activity>
+        <activity android:name=".ui.CreateAccount" android:label="@string/create_account_name">
+        </activity>
+        <activity android:name=".ui.ContactList" android:label="@string/contact_list_name">
+        </activity>
 		<service android:name="BeemService" android:enabled="true"
 			android:label="Beem Service" android:permission="com.beem.project.beem.BEEM_SERVICE">
 			<intent-filter>
@@ -32,5 +39,5 @@
 	<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
 	<uses-permission android:name="com.beem.project.beem.BEEM_SERVICE"></uses-permission>
 	<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
-	<uses-sdk android:minSdkVersion="2"></uses-sdk>
+	<uses-sdk android:minSdkVersion="3"></uses-sdk>
 </manifest> 
Binary file libs/jlibrtp-0.2.2.jar has changed
Binary file res/drawable/background.png has changed
Binary file res/drawable/icon.png has changed
Binary file res/drawable/logo.png has changed
--- a/res/layout/contactdialog.xml	Sat May 23 20:59:27 2009 +0200
+++ b/res/layout/contactdialog.xml	Fri May 29 20:34:30 2009 +0200
@@ -4,18 +4,18 @@
 	android:layout_height="fill_parent">
 
 	<Button android:id="@+id/CDChat" android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:text="Chat" />
+		android:layout_height="wrap_content" android:text="@string/CDChat" />
 
 	<Button android:id="@+id/CDAlias" android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:text="Alias" />
+		android:layout_height="wrap_content" android:text="@string/CDAlias" />
 
 	<Button android:id="@+id/CDGroup" android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:text="Change group" />
+		android:layout_height="wrap_content" android:text="@string/CDGroup" />
 
 	<Button android:id="@+id/CDResend" android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:text="Resend suscription" />
+		android:layout_height="wrap_content" android:text="@string/CDResend" />
 
 	<Button android:id="@+id/CDInfos" android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:text="User infos" />
+		android:layout_height="wrap_content" android:text="@string/CDInfos" />
 
 </LinearLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/contactdialogaliasdialog.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical" android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+
+	<EditText android:id="@+id/CDAliasDialogName"
+		android:layout_width="fill_parent" android:layout_height="wrap_content" />
+
+	<Button android:id="@+id/CDAliasDialogOk" android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:text="@string/OkButton" />
+
+</LinearLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/create_account.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+   	android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+	<LinearLayout
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:orientation="vertical"
+		android:padding="10dip">
+    	<TextView android:id="@+id/create_account_label_username"
+    		android:layout_width="fill_parent"
+    		android:layout_height="wrap_content"
+  			android:text="@string/create_account_username"
+    		style="@style/Label" />
+		<EditText android:id="@+id/create_account_username"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content" />
+    	<TextView android:id="@+id/create_account_label_password"
+    		android:layout_width="fill_parent"
+    		android:layout_height="wrap_content"
+    		android:text="@string/create_account_password"
+    		style="@style/Label" />
+		<EditText android:id="@+id/create_account_password"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:password="true" />
+    	<TextView android:id="@+id/create_account_label_confirm_password"
+    		android:layout_width="fill_parent"
+    		android:layout_height="wrap_content"
+    		android:text="@string/create_account_confirm_password"
+    		style="@style/Label" />
+		<EditText android:id="@+id/create_account_confirm_password"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:password="true" />
+    	<View
+    		android:layout_height="21dp"
+    		android:layout_width="fill_parent" />
+		<Button android:id="@+id/create_account_button"
+			android:layout_width="fill_parent"
+			android:layout_height="fill_parent"
+			android:text="@string/button_create_account" />
+	</LinearLayout>
+</ScrollView>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/edit_settings.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TabHost android:id="@+id/settings_tab_host" xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<LinearLayout 
+		android:orientation="vertical"
+    	android:layout_width="fill_parent"
+    	android:layout_height="fill_parent">
+    	<TabWidget android:id="@android:id/tabs"
+    		android:layout_width="fill_parent"
+    		android:layout_height="wrap_content" />
+    	<FrameLayout android:id="@android:id/tabcontent"
+    		android:layout_width="fill_parent"
+    		android:layout_height="fill_parent">
+    		
+    		<!--
+    			Account Tab
+    		-->
+    		<ScrollView
+    			android:orientation="vertical"
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent">
+    		<RelativeLayout android:id="@+id/settings_account"
+    			android:orientation="vertical"
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent"
+    			android:padding="10dip">
+    			<TextView android:id="@+id/settings_account_label_username"
+    				android:layout_width="fill_parent"
+    				android:layout_height="wrap_content"
+    				android:text="@string/settings_account_username"
+    				style="@style/Label" />
+				<EditText android:id="@+id/settings_account_username"
+					android:layout_width="fill_parent"
+					android:layout_height="wrap_content"
+					android:layout_below="@id/settings_account_label_username" />
+    			<TextView android:id="@+id/settings_account_label_password"
+    				android:layout_width="fill_parent"
+    				android:layout_height="wrap_content"
+					android:layout_below="@id/settings_account_username"
+    				android:text="@string/settings_account_password"
+    				style="@style/Label" />
+				<EditText android:id="@+id/settings_account_password"
+					android:layout_width="fill_parent"
+					android:layout_height="wrap_content"
+					android:layout_below="@id/settings_account_label_password"
+					android:password="true" />
+    			<Button android:id="@+id/settings_account_button_save"
+					android:layout_width="wrap_content"
+					android:layout_height="wrap_content"
+					android:layout_below="@id/settings_account_password"
+					android:layout_alignParentRight="true"
+					android:text="@string/button_save" />
+    		</RelativeLayout>
+    		</ScrollView>
+    		
+    		<!-- 
+    			XMPP Tab
+    		-->
+    		<ScrollView
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent"
+    			android:orientation="vertical">
+    		<RelativeLayout android:id="@+id/settings_xmpp"
+    			android:orientation="vertical"
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent"
+    			android:padding="10dip">
+	  			<TableLayout android:id="@+id/settings_xmpp_table_sp"
+  					android:layout_width="fill_parent"
+  					android:layout_height="wrap_content"
+  					android:stretchColumns="1">
+  					<TableRow>
+   						<TextView android:id="@+id/settings_xmpp_label_server"
+   							android:layout_column="1"
+  							android:layout_width="223dp"
+  							android:layout_height="wrap_content"
+  							android:text="@string/settings_xmpp_server"
+  							style="@style/Label" />
+  						<TextView android:id="@+id/settings_xmpp_label_port"
+  							android:layout_column="2"
+  							android:layout_width="wrap_content"
+  							android:layout_height="wrap_content"
+  							android:text="@string/settings_xmpp_port"
+  							style="@style/Label" />
+					</TableRow>
+					<TableRow>
+						<EditText android:id="@+id/settings_xmpp_server"
+							android:layout_column="1"
+							android:layout_width="wrap_content"
+							android:layout_height="wrap_content" />
+						<EditText android:id="@+id/settings_xmpp_port"
+							android:layout_column="2"
+							android:layout_width="wrap_content"
+							android:layout_height="wrap_content"
+							android:minWidth="77dp"
+							android:numeric="integer"
+							android:maxLength="5" />
+					</TableRow>
+				</TableLayout>
+    			<CheckBox android:id="@+id/settings_xmpp_use_tls"
+    				android:layout_width="wrap_content"
+    				android:layout_height="wrap_content"
+    				android:text="@string/settings_xmpp_use_tls"
+    				android:layout_below="@id/settings_xmpp_table_sp"
+    				style="@style/Label" />
+				<Button android:id="@+id/settings_xmpp_button_save"
+					android:layout_width="wrap_content"
+					android:layout_height="wrap_content"
+					android:layout_alignParentRight="true"
+					android:layout_below="@id/settings_xmpp_use_tls"
+					android:text="@string/button_save" />
+    		</RelativeLayout>
+    		</ScrollView>
+    		
+    		<!--
+    			Proxy Tab
+    		-->
+    		<ScrollView
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent"
+    			android:orientation="vertical">
+    		<RelativeLayout android:id="@+id/settings_proxy"
+    			android:orientation="vertical"
+    			android:layout_width="fill_parent"
+    			android:layout_height="fill_parent"
+    			android:padding="10dip">
+    			<CheckBox android:id="@+id/settings_proxy_use"
+    				android:layout_width="wrap_content"
+    				android:layout_height="wrap_content"
+    				android:text="@string/settings_proxy_use"
+    				style="@style/Label" />
+    			<LinearLayout android:id="@+id/settings_proxy_parameters"
+    				android:layout_width="fill_parent"
+    				android:layout_height="fill_parent"
+    				android:layout_below="@id/settings_proxy_use"
+    				android:orientation="vertical">
+    				<Spinner android:id="@+id/settings_proxy_type"
+    					android:layout_width="fill_parent"
+    					android:layout_height="wrap_content" />
+    				<TableLayout android:id="@+id/settings_proxy_table_sp"
+    					android:layout_width="fill_parent"
+    					android:layout_height="wrap_content"
+    					android:stretchColumns="1">
+    					<TableRow>
+     						<TextView android:id="@+id/settings_proxy_label_server"
+     							android:layout_column="1"
+    							android:layout_width="223dp"
+    							android:layout_height="wrap_content"
+    							android:text="@string/settings_proxy_server"
+    							style="@style/Label" />
+    						<TextView android:id="@+id/settings_proxy_label_port"
+    							android:layout_column="2"
+    							android:layout_width="wrap_content"
+    							android:layout_height="wrap_content"
+    							android:text="@string/settings_proxy_port"
+    							style="@style/Label" />
+						</TableRow>
+						<TableRow>
+							<EditText android:id="@+id/settings_proxy_server"
+								android:layout_column="1"
+								android:layout_width="wrap_content"
+								android:layout_height="wrap_content" />
+							<EditText android:id="@+id/settings_proxy_port"
+								android:layout_column="2"
+								android:layout_width="wrap_content"
+								android:layout_height="wrap_content"
+								android:minWidth="77dp"
+								android:numeric="integer"
+								android:maxLength="5" />
+						</TableRow>
+					</TableLayout>
+     				<TextView android:id="@+id/settings_proxy_label_username"
+    					android:layout_width="fill_parent"
+    					android:layout_height="wrap_content"
+    					android:text="@string/settings_proxy_username"
+    					style="@style/Label" />
+					<EditText android:id="@+id/settings_proxy_username"
+						android:layout_width="fill_parent"
+						android:layout_height="wrap_content" />
+     				<TextView android:id="@+id/settings_proxy_label_password"
+    					android:layout_width="fill_parent"
+    					android:layout_height="wrap_content"
+    					android:text="@string/settings_proxy_password"
+    					style="@style/Label" />
+					<EditText android:id="@+id/settings_proxy_password"
+						android:layout_width="fill_parent"
+						android:layout_height="wrap_content"
+    					android:password="true" />
+				</LinearLayout>
+				<Button android:id="@+id/settings_proxy_button_save"
+					android:layout_width="wrap_content"
+					android:layout_height="wrap_content"
+					android:layout_alignParentRight="true"
+					android:text="@string/button_save" />
+    		</RelativeLayout>
+    		</ScrollView>
+    	</FrameLayout>
+	</LinearLayout>
+</TabHost>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/login.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+<RelativeLayout
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dip">
+	<ImageView android:id="@+id/log_as_logo"
+		android:src="@drawable/logo"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:adjustViewBounds="true"
+		android:scaleType="center"
+		android:layout_marginTop="10px" />
+</RelativeLayout>
+</ScrollView>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/menu/contact_list.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+	<item android:id="@+id/contact_list_menu_add_contact"
+		android:visible="true"
+		android:title="@string/contact_list_menu_add_contact" />
+	<item android:id="@+id/contact_list_menu_settings"
+		android:visible="true"
+		android:title="@string/contact_list_menu_settings" />
+</menu>
--- a/res/menu/contactlistmenu.xml	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-	<item android:title="@string/MenuConnection" android:id="@+id/account_edit" android:icon="@drawable/xmpp"/>
-	<item android:title="@string/MenuAddContact" android:id="@+id/add_contact" android:icon="@drawable/buddie_robot"/>
-	<item android:title="@string/MenuAccountAbout" android:id="@+id/account_about" android:icon="@drawable/signal"/>
-	<item android:title="@string/MenuAccountCreate" android:id="@+id/account_create"/>
-</menu>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/menu/create_account.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,2 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+</menu>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/menu/edit_settings.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+	<item android:id="@+id/settings_menu_create_account"
+		android:visible="true"
+		android:title="@string/settings_menu_create_account" />
+	<item android:id="@+id/settings_menu_login"
+		android:visible="true"
+		android:title="@string/settings_menu_login" />
+</menu>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/menu/login.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+	<item android:id="@+id/login_menu_settings"
+		android:visible="true"
+		android:title="@string/login_menu_settings" />
+	<item android:id="@+id/login_menu_about"
+		android:visible="true"
+		android:title="@string/login_menu_about" />
+</menu>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/values/arrays.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<string-array name="proxy_types">
+		<item>HTTP</item>
+		<item>SOCKS4</item>
+		<item>SOCKS5</item>
+	</string-array>
+</resources>
--- a/res/values/strings.xml	Sat May 23 20:59:27 2009 +0200
+++ b/res/values/strings.xml	Fri May 29 20:34:30 2009 +0200
@@ -52,6 +52,13 @@
 	<string name="CLSLogin">Login:</string>
 	<string name="CLSOkButton">Ok</string>
 	
+	<!--  ContactDialog class -->
+	<string name="CDChat">Chat</string>
+	<string name="CDAlias">Alias</string>
+	<string name="CDGroup">Change group</string>
+	<string name="CDResend">Resend suscription</string>
+	<string name="CDInfos">User infos</string>
+	
 	<!-- AccountCreation class -->
 	<string name="ACLogin">Login:</string>
 	<string name="ACEmail">Email:</string>
@@ -103,5 +110,126 @@
 
 	<!--  BeemChatManager -->
 	<string name="BeemChatManagerNewMessage">You have got a new message</string>
+	
+    <!--
+    	Services
+    -->
+    
+    <!--
+    	Activities
+    -->
+    <string name="login_tag">BEEM - Login Activity</string>
+    
+    <string name="edit_settings_name">BEEM - Settings</string>
+	<string name="edit_settings_tag">BEEM - EditSettings Activity</string>
+	
+    <string name="create_account_name">BEEM - Create an account</string>
+    <string name="create_account_tag">BEEM - CreateAccount Activity</string>
+    
+    <string name="contact_list_name">BEEM - Contacts</string>
+    <string name="contact_list_tag">BEEM - ContactList Activity</string>
+
+    
+    <!--
+    	Buttons
+    -->
+    <string name="button_reset">Reset</string>
+    <string name="button_login">Login</string>
+    <string name="button_save">Save</string>
+    <string name="button_create_account">Create this account</string>
+    
+    
+    <!--
+    	LogAs Activity
+    -->
+	<string name="login_username">Username</string>
+	<string name="login_password">Password</string>
+	
+	<string name="login_error_dialog_title">Login - Error</string>
+	<string name="login_close_dialog_button">Close</string>
+	
+	<string name="login_menu_create_account">Create an account</string>
+	<string name="login_menu_settings">Settings</string>
+	<string name="login_menu_about">About</string>
+	
+	<string name="login_about_title">About</string>
+	<string name="login_about_msg">
+		BEEM is an EPITECH Innovative Project. Visit us at http://www.beem-project.com !
+	</string>
+	<string name="login_about_button">Close</string>
+	
+	
+	<!--
+		EditSettings Activity
+	-->
+	<string name="settings_menu_create_account">Create an account</string>
+	<string name="settings_menu_login">Login</string>
+
+	<string name="settings_saved_ok">The settings have been saved successfully.</string>
+	
+	<string name="settings_filename">beem_settings</string>
+	<string name="settings_key_account_username">beem_account_username</string>
+	<string name="settings_key_account_password">beem_account_password</string>
+	<string name="settings_key_xmpp_server">beem_xmpp_server</string>
+	<string name="settings_key_xmpp_port">beem_xmpp_port</string>
+	<string name="settings_key_xmpp_tls_use">beem_xmpp_tls_use</string>
+	<string name="settings_key_proxy_use">beem_xmpp_proxy_use</string>
+	<string name="settings_key_proxy_server">beem_xmpp_proxy_server</string>
+	<string name="settings_key_proxy_port">beem_xmpp_proxy_port</string>
+	<string name="settings_key_proxy_username">beem_xmpp_proxy_username</string>
+	<string name="settings_key_proxy_password">beem_xmpp_proxy_password</string>
+	<string name="settings_key_proxy_type">beem_xmpp_proxy_type</string>
+	
+	<!-- EditSettings Activity tabs -->
+	<string name="settings_tab_tag_account">edit_settings_tab_account</string>
+	<string name="settings_tab_label_account">Account</string>
+	
+	<string name="settings_tab_tag_xmpp">edit_settings_tab_xmpp</string>
+	<string name="settings_tab_label_xmpp">XMPP</string>
+	
+	<string name="settings_tab_tag_proxy">edit_settings_tab_proxy</string>
+	<string name="settings_tab_label_proxy">Proxy</string>
+	
+	<!-- EditSettings Activity Account tab -->
+	<string name="settings_account_username">Username</string>
+	<string name="settings_account_password">Password</string>
+	<string name="settings_account_server">Server</string>
+	<string name="settings_account_port">Port</string>
+	
+	
+	<!-- EditSettings Activity XMPP tab -->
+	<string name="settings_xmpp_server">Server</string>
+	<string name="settings_xmpp_port">Port</string>
+	<string name="settings_xmpp_use_tls">Require SSL/TLS</string>
+	
+	<!-- EditSettings Activity Proxy tab -->
+	<string name="settings_proxy_use">Connect using a proxy</string>
+	<string name="settings_proxy_type_prompt">Choose a type of proxy</string>
+	<string name="settings_proxy_server">Server</string>
+	<string name="settings_proxy_port">Port</string>
+	<string name="settings_proxy_username">Username</string>
+	<string name="settings_proxy_password">Password</string>
+	
+	<!--
+		Create an account Activity
+	-->
+	<string name="create_account_instr_dialog_title">Create an account - Instructions</string>
+	<string name="create_account_err_dialog_title">Create an account - Error</string>
+	<string name="create_account_err_dialog_settings_button">Change my settings</string>
+	<string name="create_account_close_dialog_button">Close</string>
+
+	
+	<string name="create_account_successfull_after">has been created successfully</string>
+	<string name="create_account_err_passwords">Passwords do not match.</string>
+	
+	<string name="create_account_username">Username</string>
+	<string name="create_account_password">Password</string>
+	<string name="create_account_confirm_password">Confirm password</string>
+	
+	<!--
+		ContactList Activity 
+	 -->
+	 <string name="contact_list_menu_add_contact">Add a contact</string>
+	 <string name="contact_list_menu_settings">Settings</string>
 
 </resources>
--- a/res/values/style.xml	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-	<style name="customtheme" parent="android:Theme">
-	</style>
-
-	<style name="customtheme.contactList">
-		<item name="android:windowBackground">@drawable/background</item>
-		<item name="android:windowNoTitle">true</item>
-		<item name="android:textColor">#000000</item>
-		<item name="android:typeface">sans</item>
-		<item name="android:textSize">18sp</item>
-
-	</style>
-
-	<style name="customtheme.jungle">
-		<item name="android:windowBackground">@drawable/background</item>
-		<item name="android:windowNoTitle">true</item>
-		<item name="android:textColor">#FFFFFF</item>
-		<item name="android:typeface">sans</item>
-		<item name="android:textSize">18sp</item>
-	</style>
-
-	<style name="customtheme.spinner">
-		<item name="android:windowBackground">@drawable/background</item>
-		<item name="android:windowNoTitle">true</item>
-		<item name="android:textColor">#FF0000</item>
-		<item name="android:typeface">sans</item>
-		<item name="android:textSize">18sp</item>
-	</style>
-
-</resources>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/values/styles.xml	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style name="Label">
+		<item name="android:textSize">16sp</item>
+		<item name="android:textStyle">bold</item>
+		<item name="android:typeface">sans</item>
+		<item name="android:capitalize">characters</item>
+		<item name="android:textColor">#FFFFFF</item>
+	</style>
+	<style name="Theme.BEEM.Default" parent="@android:style/Theme">
+		<item name="android:windowBackground">@drawable/background</item>
+	</style>
+</resources>
--- a/src/com/beem/project/beem/BeemApplication.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/BeemApplication.java	Fri May 29 20:34:30 2009 +0200
@@ -26,183 +26,14 @@
 
 /**
  * The Beem application. This class has some methods utiliy needs by the activities.
+ * 
  * @author darisk
  */
 public class BeemApplication extends Application {
 
-    private static BeemApplication mBeemApp;
-    private Activity mActivity;
-    private static final Intent SERVICE_INTENT = new Intent();
-    public static final String TAG = "BeemApplication";
-    private IXmppFacade mFacade;
-    private Context mApplicationContext;
-    private List<Message> mQueue = new LinkedList<Message>();
-    private boolean mIsConnected;
-    private IXmppConnection mConnection;
-    private ProgressDialog mProgressDialog;
-    private ConnectionListener mConnectionListener = new ConnectionListener();
-
-    static {
-	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
-    }
-
-    private ServiceConnection mServConn = new ServiceConnection() {
-
-	@Override
-	public void onServiceDisconnected(ComponentName name) {
-	    mFacade = null;
-	    mIsConnected = false;
-	}
-
-	@Override
-	public void onServiceConnected(ComponentName name, IBinder service) {
-	    mIsConnected = true;
-	    mFacade = IXmppFacade.Stub.asInterface(service);
-	    try {
-		mConnection = mFacade.createConnection();
-		if (!mConnection.isAuthentificated()) {
-		    mConnection.addConnectionListener(mConnectionListener);
-		    mApplicationContext.startService(BeemApplication.SERVICE_INTENT);
-		}else {
-		    mProgressDialog.dismiss();
-		    synchronized (mQueue) {
-			for (Message msg : mQueue) {
-			    msg.sendToTarget();
-			}
-			mQueue.clear();
-		    }
-		}
-	    } catch (RemoteException e) {
-		Log.e(TAG, "service connection exception", e);
-	    }
-	}
-    };
-
-    /**
-     * Constructor.
-     */
-    public BeemApplication() {
-	mIsConnected = false;
-    }
-
-    /**
-     * Get the Beem application for an activity.
-     * @param activity the activity which want the Beem application
-     * @return the Beem application
-     */
-    public static BeemApplication getApplication(Activity activity) {
-	if (mBeemApp == null) {
-	    mBeemApp = new BeemApplication();
-	}
-	mBeemApp.mActivity = activity;
-	mBeemApp.mProgressDialog = new ProgressDialog(activity);
-	mBeemApp.mProgressDialog.setTitle("Beem");
-	mBeemApp.mProgressDialog.setIcon(R.drawable.signal);
-	mBeemApp.mProgressDialog.setMessage("Connecting...");
-	mBeemApp.mProgressDialog.setCancelable(true);
-	
-	mBeemApp.mApplicationContext = activity.getApplication();
-	activity.getResources();
-	mBeemApp.onCreate();
-	//mBeemApp.mProgressDialog.show();
-	return mBeemApp;
-    }
-
-    /**
-     * Start the beem service.
-     */
-    public synchronized void startBeemService() {
-	if (!mIsConnected) {
-	    ConnectionRunnable cRun = new ConnectionRunnable("Connecting...");
-	    mBeemApp.mActivity.runOnUiThread(cRun);
-	    // the connection will be made on service connect
-	    mApplicationContext.bindService(BeemApplication.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
-	}
-    }
-
-    /**
-     * Stop the Beem service.
-     */
-    public synchronized void stopBeemService() {
-	if (mIsConnected) {
-	    Intent intent = new Intent();
-	    intent.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
-	    mApplicationContext.unbindService(mServConn);
-	    mApplicationContext.stopService(intent);
-	    mIsConnected = false;
-	}
-    }
-
-    public synchronized void unbindBeemService() {
-	if (mIsConnected) {
-	    mApplicationContext.unbindService(mServConn);
-	    mIsConnected = false;
-	}
-     }
-
-    /**
-     * Get the facade to use to access the Beem service.
-     * @return the facade or null if the application is not connected to the beem service.
-     */
-    public IXmppFacade getXmppFacade() {
-	return mFacade;
-    }
-
-    /**
-     * Add a methode to execute when the application is connected to the server.
-     * @param target the handler which will execute the callback
-     * @param callback the callback to execute
-     */
-    public void callWhenConnectedToServer(Handler target, Runnable callback) {
-	Message msg = Message.obtain(target, callback);
-	if (mIsConnected) {
-	    msg.sendToTarget();
-	} else {
-	    startBeemService();
-	    synchronized (mQueue) {
-		mQueue.add(msg);
-	    }
-	}
-    }
-
-    /**
-     * Tell if we are connected with the Beem Service.
-     * @return true if connected false otherwise
-     */
-    public boolean isConnected() {
-	return mIsConnected;
-    }
-
-    private class ConnectionRunnable implements Runnable {
-	private String mErrorMsg;
-
-	public ConnectionRunnable(String string) {
-	    this.mErrorMsg = string;
-	}
-
-	@Override
-	public void run() {
-	    mBeemApp.mProgressDialog.setMessage(mErrorMsg);
-	}
-
-	/**
-	 * @param mErrorMsg the mErrorMsg to set
-	 */
-	public void setMErrorMsg(String mErrorMsg) {
-	    this.mErrorMsg = mErrorMsg;
-	}
-
-	/**
-	 * @return the mErrorMsg
-	 */
-	public String getMErrorMsg() {
-	    return mErrorMsg;
-	}
-
-    }
-
     /**
      * Connection listener use to hide the progress dialog.
+     * 
      * @author darisk
      */
     private class ConnectionListener extends IBeemConnectionListener.Stub {
@@ -231,6 +62,13 @@
 	    // TODO afficher une notification et reafficher le progress dialog
 	}
 
+	@Override
+	public void connectionFailed(String errorMsg) throws RemoteException {
+	    Log.i(TAG, "Connection Failed");
+	    ConnectionRunnable cRun = new ConnectionRunnable(errorMsg);
+	    mBeemApp.mActivity.runOnUiThread(cRun);
+	}
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -269,13 +107,193 @@
 	public void reconnectionSuccessful() throws RemoteException {
 	}
 
+    }
+
+    private class ConnectionRunnable implements Runnable {
+
+	private String mErrorMsg;
+
+	public ConnectionRunnable(String string) {
+	    this.mErrorMsg = string;
+	}
+
+	/**
+	 * @return the mErrorMsg
+	 */
+	public String getMErrorMsg() {
+	    return mErrorMsg;
+	}
+
 	@Override
-	public void connectionFailed(String errorMsg) throws RemoteException {
-	    Log.i(TAG, "Connection Failed");
-	    ConnectionRunnable cRun = new ConnectionRunnable(errorMsg);
-	    mBeemApp.mActivity.runOnUiThread(cRun);
+	public void run() {
+	    mBeemApp.mProgressDialog.setMessage(mErrorMsg);
+	}
+
+	/**
+	 * @param mErrorMsg
+	 *            the mErrorMsg to set
+	 */
+	public void setMErrorMsg(String mErrorMsg) {
+	    this.mErrorMsg = mErrorMsg;
 	}
 
     }
 
+    private static final Intent    SERVICE_INTENT = new Intent();
+    private static BeemApplication mBeemApp;
+    static {
+	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
+    }
+
+    /**
+     * Get the Beem application for an activity.
+     * 
+     * @param activity
+     *            the activity which want the Beem application
+     * @return the Beem application
+     */
+    public static BeemApplication getApplication(Activity activity) {
+	if (mBeemApp == null) {
+	    mBeemApp = new BeemApplication();
+	}
+	mBeemApp.mActivity = activity;
+	mBeemApp.mProgressDialog = new ProgressDialog(activity);
+	mBeemApp.mProgressDialog.setTitle("Beem");
+	mBeemApp.mProgressDialog.setIcon(R.drawable.signal);
+	mBeemApp.mProgressDialog.setMessage("Connecting...");
+	mBeemApp.mProgressDialog.setCancelable(true);
+
+	mBeemApp.mApplicationContext = activity.getApplication();
+	activity.getResources();
+	mBeemApp.onCreate();
+	// mBeemApp.mProgressDialog.show();
+	return mBeemApp;
+    }
+
+    private Activity                 mActivity;
+    public static final String       TAG                 = "BeemApplication";
+    private IXmppFacade              mFacade;
+    private Context                  mApplicationContext;
+    private final List<Message>      mQueue              = new LinkedList<Message>();
+
+    private boolean                  mIsConnected;
+
+    private IXmppConnection          mConnection;
+
+    private ProgressDialog           mProgressDialog;
+
+    private final ConnectionListener mConnectionListener = new ConnectionListener();
+
+    private final ServiceConnection  mServConn           = new ServiceConnection() {
+
+	                                                     @Override
+	                                                     public void onServiceConnected(ComponentName name,
+	                                                             IBinder service) {
+		                                                 mIsConnected = true;
+		                                                 mFacade = IXmppFacade.Stub.asInterface(service);
+		                                                 try {
+		                                                     mConnection = mFacade.createConnection();
+		                                                     if (!mConnection.isAuthentificated()) {
+			                                                 mConnection
+			                                                         .addConnectionListener(mConnectionListener);
+			                                                 mApplicationContext
+			                                                         .startService(BeemApplication.SERVICE_INTENT);
+		                                                     } else {
+			                                                 mProgressDialog.dismiss();
+			                                                 synchronized (mQueue) {
+			                                                     for (Message msg : mQueue) {
+				                                                 msg.sendToTarget();
+			                                                     }
+			                                                     mQueue.clear();
+			                                                 }
+		                                                     }
+		                                                 } catch (RemoteException e) {
+		                                                     Log.e(TAG, "service connection exception", e);
+		                                                 }
+	                                                     }
+
+	                                                     @Override
+	                                                     public void onServiceDisconnected(ComponentName name) {
+		                                                 mFacade = null;
+		                                                 mIsConnected = false;
+	                                                     }
+	                                                 };
+
+    /**
+     * Constructor.
+     */
+    public BeemApplication() {
+	mIsConnected = false;
+    }
+
+    /**
+     * Add a methode to execute when the application is connected to the server.
+     * 
+     * @param target
+     *            the handler which will execute the callback
+     * @param callback
+     *            the callback to execute
+     */
+    public void callWhenConnectedToServer(Handler target, Runnable callback) {
+	Message msg = Message.obtain(target, callback);
+	if (mIsConnected) {
+	    msg.sendToTarget();
+	} else {
+	    startBeemService();
+	    synchronized (mQueue) {
+		mQueue.add(msg);
+	    }
+	}
+    }
+
+    /**
+     * Get the facade to use to access the Beem service.
+     * 
+     * @return the facade or null if the application is not connected to the beem service.
+     */
+    public IXmppFacade getXmppFacade() {
+	return mFacade;
+    }
+
+    /**
+     * Tell if we are connected with the Beem Service.
+     * 
+     * @return true if connected false otherwise
+     */
+    public boolean isConnected() {
+	return mIsConnected;
+    }
+
+    /**
+     * Start the beem service.
+     */
+    public synchronized void startBeemService() {
+	if (!mIsConnected) {
+	    ConnectionRunnable cRun = new ConnectionRunnable("Connecting...");
+	    mBeemApp.mActivity.runOnUiThread(cRun);
+	    // the connection will be made on service connect
+	    mApplicationContext.bindService(BeemApplication.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
+	}
+    }
+
+    /**
+     * Stop the Beem service.
+     */
+    public synchronized void stopBeemService() {
+	if (mIsConnected) {
+	    Intent intent = new Intent();
+	    intent.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
+	    mApplicationContext.unbindService(mServConn);
+	    mApplicationContext.stopService(intent);
+	    mIsConnected = false;
+	}
+    }
+
+    public synchronized void unbindBeemService() {
+	if (mIsConnected) {
+	    mApplicationContext.unbindService(mServConn);
+	    mIsConnected = false;
+	}
+    }
+
 }
--- a/src/com/beem/project/beem/BeemException.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/BeemException.java	Fri May 29 20:34:30 2009 +0200
@@ -8,53 +8,57 @@
 
 /**
  * @author darisk
- *
  */
-public class BeemException extends Exception implements Parcelable  {
+public class BeemException extends Exception implements Parcelable {
 
     /**
 	 * 
 	 */
-	private static final long serialVersionUID = -5794514989326146456L;
-	public static final Parcelable.Creator<BeemException> CREATOR = new Creator<BeemException>() {
-    
-        @Override
-        public BeemException[] newArray(int size) {
-    	// TODO Auto-generated method stub
-    	   return new BeemException[size];
-        }
-    
-        @Override
-        public BeemException createFromParcel(Parcel source) {
-    	// TODO Auto-generated method stub
-    	    return new BeemException(source);
-        }
-    };
-    
+    private static final long                             serialVersionUID = -5794514989326146456L;
+    public static final Parcelable.Creator<BeemException> CREATOR          = new Creator<BeemException>() {
+
+	                                                                       @Override
+	                                                                       public BeemException createFromParcel(
+	                                                                               Parcel source) {
+		                                                                   // TODO
+		                                                                   // Auto-generated
+		                                                                   // method stub
+		                                                                   return new BeemException(source);
+	                                                                       }
+
+	                                                                       @Override
+	                                                                       public BeemException[] newArray(int size) {
+		                                                                   // TODO
+		                                                                   // Auto-generated
+		                                                                   // method stub
+		                                                                   return new BeemException[size];
+	                                                                       }
+	                                                                   };
+
     public BeemException() {
 	super();
 	// TODO Auto-generated constructor stub
     }
 
+    private BeemException(Parcel parcel) {
+	this(parcel.readString());
+    }
+
+    public BeemException(String detailMessage) {
+	super(detailMessage);
+	// TODO Auto-generated constructor stub
+    }
+
     public BeemException(String detailMessage, Throwable throwable) {
 	super(detailMessage, throwable);
 	// TODO Auto-generated constructor stub
     }
 
-    public BeemException(String detailMessage) {
-	super(detailMessage);
-	// TODO Auto-generated constructor stub
-    }
-
     public BeemException(Throwable throwable) {
 	super(throwable);
 	// TODO Auto-generated constructor stub
     }
-    
-    private BeemException(Parcel parcel){
-	this(parcel.readString());
-    }
-     
+
     @Override
     public int describeContents() {
 	// TODO Auto-generated method stub
@@ -67,5 +71,4 @@
 	dest.writeString(getLocalizedMessage());
     }
 
-    
 }
--- a/src/com/beem/project/beem/BeemService.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Fri May 29 20:34:30 2009 +0200
@@ -10,6 +10,7 @@
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.proxy.ProxyInfo;
 import org.jivesoftware.smack.proxy.ProxyInfo.ProxyType;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -27,8 +28,9 @@
 import com.beem.project.beem.ui.Subscription;
 
 /**
- * This class is for the Beem service. The connection to the xmpp server will be made asynchronously when the service
- * will start.
+ * This class is for the Beem service. The connection to the xmpp server will be made asynchronously
+ * when the service will start.
+ * 
  * @author darisk
  */
 public class BeemService extends Service {
@@ -36,20 +38,20 @@
     /**
      * The id to use for status notification.
      */
-    public static final int NOTIFICATION_STATUS_ID = 100;
+    public static final int         NOTIFICATION_STATUS_ID = 100;
 
-    private NotificationManager mNotificationManager;
-    private XmppConnectionAdapter mConnection;
-    private SharedPreferences mSettings;
-    private String mLogin;
-    private String mPassword;
-    private String mHost;
-    private String mService;
-    private int mPort;
+    private NotificationManager     mNotificationManager;
+    private XmppConnectionAdapter   mConnection;
+    private SharedPreferences       mSettings;
+    private String                  mLogin;
+    private String                  mPassword;
+    private String                  mHost;
+    private String                  mService;
+    private int                     mPort;
     private ConnectionConfiguration mConnectionConfiguration;
-    private ProxyInfo mProxyInfo;
-    private boolean mUseProxy;
-    private IXmppFacade.Stub mBind;
+    private ProxyInfo               mProxyInfo;
+    private boolean                 mUseProxy;
+    private IXmppFacade.Stub        mBind;
 
     /**
      * Constructor.
@@ -58,67 +60,11 @@
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-	return mBind;
-	// to forbid a client to bind
-	// return null;
-    }
-
-    /**
-     * {@inheritDoc}
+     * Close the connection to the xmpp server.
      */
-    @Override
-    public void onCreate() {
-
-	super.onCreate();
-	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
-	mLogin = mSettings.getString(getString(R.string.PreferenceLoginKey), "");
-	mPassword = mSettings.getString(getString(R.string.PreferencePasswordKey), "");
-	mHost = mSettings.getString(getString(R.string.PreferenceHostKey), "");
-	mPort = mSettings.getInt(getString(R.string.PreferencePortKey), 5222);
-	if (mHost.equals("talk.google.com"))
-	    mService = "gmail.com";
-	else
-	    mService = null;
-	initConnectionConfig();
-	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
-	initRosterRequestListener();
-	mBind = new XmppFacade(mConnection, this);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onStart(Intent intent, int startId) {
-	try {
-	    mConnection.connectAsync();
-	} catch (RemoteException e) {
-	    // TODO Auto-generated catch block
-	    e.printStackTrace();
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onDestroy() {
-	closeConnection();
-	mNotificationManager.cancel(NOTIFICATION_STATUS_ID);
-    }
-
-    /**
-     * Show a notification.
-     * @param id the id of the notification.
-     * @param notif the notification to show
-     */
-    public void sendNotification(int id, Notification notif) {
-	mNotificationManager.notify(id, notif);
+    private void closeConnection() {
+	if (mConnection != null)
+	    mConnection.disconnect();
     }
 
     /**
@@ -126,14 +72,14 @@
      */
     private void initConnectionConfig() {
 	// TODO mettre a false par defaut et remplacer les valeurs par defaut
-	mUseProxy = mSettings.getBoolean(getString(R.string.PreferenceUseProxy), false);
+	mUseProxy = mSettings.getBoolean(getString(R.string.settings_key_proxy_use), false);
 	if (mUseProxy) {
 	    String stype = mSettings.getString(getString(R.string.PreferenceProxyType),
-		getString(R.string.PreferenceProxyTypeHttp));
-	    String phost = mSettings.getString(getString(R.string.PreferenceProxyHost), "");
-	    String puser = mSettings.getString(getString(R.string.PreferenceProxyUser), "");
-	    String ppass = mSettings.getString(getString(R.string.PreferenceProxyPassword), "");
-	    int pport = mSettings.getInt(getString(R.string.PreferenceProxyPort), 1080);
+		    getString(R.string.PreferenceProxyTypeHttp));
+	    String phost = mSettings.getString(getString(R.string.settings_key_proxy_server), "");
+	    String puser = mSettings.getString(getString(R.string.settings_key_proxy_username), "");
+	    String ppass = mSettings.getString(getString(R.string.settings_key_proxy_password), "");
+	    int pport = Integer.parseInt(mSettings.getString(getString(R.string.settings_key_proxy_port), "1080"));
 	    ProxyInfo.ProxyType type = ProxyType.valueOf(stype);
 	    mProxyInfo = new ProxyInfo(type, phost, pport, puser, ppass);
 	    if (mService != null)
@@ -154,10 +100,78 @@
 	Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
 	final XMPPConnection con = mConnection.getAdaptee();
 	try {
-	    // l'ajout d'un packet listener ne peut etre effectuer que lorsqu'on est connecte au serveur
+	    // l'ajout d'un packet listener ne peut etre effectuer que lorsqu'on est connecte au
+	    // serveur
 	    mConnection.addConnectionListener(new IBeemConnectionListener.Stub() {
 
 		@Override
+		public void connectionClosed() throws RemoteException {
+		    // TODO Auto-generated method stub
+
+		}
+
+		@Override
+		public void connectionClosedOnError() throws RemoteException {
+		    // TODO Auto-generated method stub
+
+		}
+
+		@Override
+		public void connectionFailed(String errorMsg) throws RemoteException {
+		    // TODO Auto-generated method stub
+
+		}
+
+		@Override
+		public void onConnect() throws RemoteException {
+
+		    PacketFilter filter = new PacketFilter() {
+
+			@Override
+			public boolean accept(Packet packet) {
+			    if (packet instanceof Presence) {
+				Presence pres = (Presence) packet;
+				if (pres.getType() == Presence.Type.subscribe)
+				    return true;
+			    }
+			    return false;
+			}
+		    };
+		    con.addPacketListener(new PacketListener() {
+
+			@Override
+			public void processPacket(Packet packet) {
+			    String from = packet.getFrom();
+			    Notification notif = new Notification(com.beem.project.beem.R.drawable.signal,
+				    "Demande d'ajout", System.currentTimeMillis());
+			    notif.defaults = Notification.DEFAULT_ALL;
+			    notif.flags = Notification.FLAG_AUTO_CANCEL;
+			    Intent intent = new Intent(BeemService.this, Subscription.class);
+			    intent.putExtra("from", from);
+			    notif
+				    .setLatestEventInfo(BeemService.this, from, "demande d'ajout de " + from,
+				            PendingIntent.getActivity(BeemService.this, 0, intent,
+				                    PendingIntent.FLAG_ONE_SHOT));
+			    int id = packet.hashCode();
+			    sendNotification(id, notif);
+			}
+		    }, filter);
+
+		}
+
+		@Override
+		public void reconnectingIn(int seconds) throws RemoteException {
+		    // TODO Auto-generated method stub
+
+		}
+
+		@Override
+		public void reconnectionFailed() throws RemoteException {
+		    // TODO Auto-generated method stub
+
+		}
+
+		@Override
 		public void reconnectionSuccessful() throws RemoteException {
 		    // TODO Auto-generated method stub
 		    PacketFilter filter = new PacketFilter() {
@@ -181,71 +195,6 @@
 			}
 		    }, filter);
 		}
-
-		@Override
-		public void reconnectionFailed() throws RemoteException {
-		    // TODO Auto-generated method stub
-
-		}
-
-		@Override
-		public void reconnectingIn(int seconds) throws RemoteException {
-		    // TODO Auto-generated method stub
-
-		}
-
-		@Override
-		public void onConnect() throws RemoteException {
-
-		    PacketFilter filter = new PacketFilter() {
-
-			@Override
-			public boolean accept(Packet packet) {
-			    if (packet instanceof Presence) {
-				Presence pres = (Presence) packet;
-				if (pres.getType() == Presence.Type.subscribe)
-				    return true;
-			    }
-			    return false;
-			}
-		    };
-		    con.addPacketListener(new PacketListener() {
-
-			@Override
-			public void processPacket(Packet packet) {
-			    String from = packet.getFrom();
-			    Notification notif = new Notification(com.beem.project.beem.R.drawable.signal,
-				"Demande d'ajout", System.currentTimeMillis());
-			    notif.defaults = Notification.DEFAULT_ALL;
-			    notif.flags = Notification.FLAG_AUTO_CANCEL;
-			    Intent intent = new Intent(BeemService.this, Subscription.class);
-			    intent.putExtra("from", from);
-			    notif.setLatestEventInfo(BeemService.this, from, "demande d'ajout de " + from,
-				PendingIntent.getActivity(BeemService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT));
-			    int id = packet.hashCode();
-			    sendNotification(id, notif);
-			}
-		    }, filter);
-
-		}
-
-		@Override
-		public void connectionClosedOnError() throws RemoteException {
-		    // TODO Auto-generated method stub
-
-		}
-
-		@Override
-		public void connectionClosed() throws RemoteException {
-		    // TODO Auto-generated method stub
-
-		}
-
-		@Override
-		public void connectionFailed(String errorMsg) throws RemoteException {
-		    // TODO Auto-generated method stub
-
-		}
 	    });
 	} catch (RemoteException e) {
 	    // TODO Auto-generated catch block
@@ -254,11 +203,75 @@
     }
 
     /**
-     * Close the connection to the xmpp server.
+     * {@inheritDoc}
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+	return mBind;
+	// to forbid a client to bind
+	// return null;
+    }
+
+    /**
+     * {@inheritDoc}
      */
-    private void closeConnection() {
-	if (mConnection != null)
-	    mConnection.disconnect();
+    @Override
+    public void onCreate() {
+
+	super.onCreate();
+	mSettings = getSharedPreferences(getString(R.string.settings_filename), MODE_PRIVATE);
+	mLogin = mSettings.getString(getString(R.string.settings_key_account_username), "");
+	mPassword = mSettings.getString(getString(R.string.settings_key_account_password), "");
+	mHost = mSettings.getString(getString(R.string.settings_key_xmpp_server), "");
+	mPort = Integer.parseInt(mSettings.getString(getString(R.string.settings_key_xmpp_port), "5222"));
+
+	Log.i("BEEMSERVICE", mLogin);
+	Log.i("BEEMSERVICE", mPassword);
+	Log.i("BEEMSERVICE", mHost);
+	Log.i("BEEMSERVICE", "" + mPort + "");
+	if (mHost.equals("talk.google.com"))
+	    mService = "gmail.com";
+	else
+	    mService = null;
+	initConnectionConfig();
+	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
+	initRosterRequestListener();
+	mBind = new XmppFacade(mConnection, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onDestroy() {
+	closeConnection();
+	mNotificationManager.cancel(NOTIFICATION_STATUS_ID);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onStart(Intent intent, int startId) {
+	try {
+	    mConnection.connectAsync();
+	} catch (RemoteException e) {
+	    // TODO Auto-generated catch block
+	    e.printStackTrace();
+	}
+    }
+
+    /**
+     * Show a notification.
+     * 
+     * @param id
+     *            the id of the notification.
+     * @param notif
+     *            the notification to show
+     */
+    public void sendNotification(int id, Notification notif) {
+	mNotificationManager.notify(id, notif);
     }
 
 }
--- a/src/com/beem/project/beem/jingle/Caller.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/Caller.java	Fri May 29 20:34:30 2009 +0200
@@ -3,6 +3,7 @@
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.jivesoftware.smack.ConnectionConfiguration;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
@@ -16,146 +17,128 @@
 
 /**
  * @author darisk
- * 
  */
 public class Caller {
 
-	private XMPPConnection con;
-	private String login;
-	private String password;
-	private JingleManager jingleManager;
-	private List<JingleMediaManager> mediaManagers;
-	private JingleSession out;
+    /**
+     * @param args
+     *            Program args
+     * @throws InterruptedException
+     *             exception
+     */
+    public static void main(final String[] args) throws InterruptedException {
+	if (args.length < 3) {
+	    System.err.println("Not enough parameters");
+	    System.err.println("Usage : Caller user password server jidtocall");
+	}
+	Caller test = new Caller(args[0], args[1], args[2]);
+	test.call("test2@nikita-rack/TEST");
+	Thread.sleep(60000);
+    }
+
+    private XMPPConnection           con;
+    private String                   login;
+    private String                   password;
+    private JingleManager            jingleManager;
+    private List<JingleMediaManager> mediaManagers;
+
+    private JingleSession            out;
+
+    public Caller(final String login, final String pass, String server) {
+	if (server == null || server.equals(""))
+	    server = "localhost";
+	// XMPPConnection.DEBUG_ENABLED = true;
+	this.login = login;
+	this.password = pass;
+	ConnectionConfiguration conf = new ConnectionConfiguration(server);
+	conf.setRosterLoadedAtLogin(false);
+
+	con = new XMPPConnection(conf);
+	try {
+	    con.connect();
+	    con.login(this.login, this.password, "Caller");
+	    initialize();
+	} catch (XMPPException e) {
+	    // TODO Auto-generated catch block
+	    System.err.println("Echec de la connexion au serveru");
+	    e.printStackTrace();
+	}
+    }
+
+    public void call(final String destinataire) {
+	try {
+	    out = jingleManager.createOutgoingJingleSession(destinataire);
+	    // TODO configure out avec addMediaSession et addNegociator
+	    out.addListener(new JingleSessionListener() {
 
-	public Caller(final String login, final String pass, String server) {
-		if (server == null || server.equals(""))
-			server = "localhost";
-		//XMPPConnection.DEBUG_ENABLED = true;
-		this.login = login;
-		this.password = pass;
-		ConnectionConfiguration conf = new ConnectionConfiguration(server);
-		conf.setRosterLoadedAtLogin(false);
+		@Override
+		public void sessionClosed(final String reason, final JingleSession jingleSession) {
+		    System.out.println("Session " + jingleSession.getResponder() + "closed because " + reason);
+		}
+
+		@Override
+		public void sessionClosedOnError(final XMPPException e, final JingleSession jingleSession) {
+		    System.out.println("Session " + jingleSession.getResponder() + " closed on error");
+
+		}
+
+		@Override
+		public void sessionDeclined(final String reason, final JingleSession jingleSession) {
+		    System.out.println("Session " + jingleSession.getResponder() + "declined because " + reason);
+		}
 
-		con = new XMPPConnection(conf);
-		try {
-			con.connect();
-			con.login(this.login, this.password, "Caller");
-			initialize();
-		} catch (XMPPException e) {
-			// TODO Auto-generated catch block
-			System.err.println("Echec de la connexion au serveru");
+		@Override
+		public void sessionEstablished(final PayloadType pt, final TransportCandidate remoteCandidate,
+		        final TransportCandidate localCandidate, final JingleSession jingleSession) {
+		    System.out.println("Session established");
+		    // String name = localCandidate.getName();
+		    String ip = localCandidate.getIp();
+		    int port = localCandidate.getPort();
+		    System.out.println("Session established waiting connection on " + ip + ":" + port);
+		    try {
+			try {
+			    FileSender fs = new FileSender(ip, port, "/tmp/img.jpeg");
+			    fs.start();
+			    fs.join();
+			    System.out.println("End of transfer");
+			} finally {
+			    jingleSession.terminate();
+			}
+		    } catch (UnknownHostException e) {
+			System.err.println("Can't create server");
+		    } catch (InterruptedException e) {
+		    } catch (XMPPException e) {
+			System.err.println("Probably lost the connection");
 			e.printStackTrace();
+		    }
 		}
+
+		@Override
+		public void sessionMediaReceived(final JingleSession jingleSession, final String participant) {
+		    // TODO Auto-generated method stub
+		    System.out.println("Session Media received from " + participant);
+		}
+
+		@Override
+		public void sessionRedirected(final String redirection, final JingleSession jingleSession) {
+		    // TODO Auto-generated method stub
+		}
+	    });
+	    out.startOutgoing();
+
+	} catch (XMPPException e) {
+	    // TODO Auto-generated catch block
+	    e.printStackTrace();
 	}
 
-	public void call(final String destinataire) {
-		try {
-			out = jingleManager.createOutgoingJingleSession(destinataire);
-			// TODO configure out avec addMediaSession et addNegociator
-			out.addListener(new JingleSessionListener() {
-
-				@Override
-				public void sessionRedirected(final String redirection,
-						final JingleSession jingleSession) {
-					// TODO Auto-generated method stub
-				}
-
-				@Override
-				public void sessionMediaReceived(
-						final JingleSession jingleSession,
-						final String participant) {
-					// TODO Auto-generated method stub
-					System.out.println("Session Media received from "
-							+ participant);
-				}
-
-				@Override
-				public void sessionEstablished(final PayloadType pt,
-						final TransportCandidate remoteCandidate,
-						final TransportCandidate localCandidate,
-						final JingleSession jingleSession) {
-					System.out.println("Session established");
-					//String name = localCandidate.getName();
-					String ip = localCandidate.getIp();
-					int port = localCandidate.getPort();
-					System.out
-							.println("Session established waiting connection on "
-									+ ip + ":" + port);
-					try {
-						try {
-							FileSender fs = new FileSender(ip, port,
-									"/tmp/img.jpeg");
-							fs.start();
-							fs.join();
-							System.out.println("End of transfer");
-						} finally {
-							jingleSession.terminate();
-						}
-					} catch (UnknownHostException e) {
-						System.err.println("Can't create server");
-					} catch (InterruptedException e) {
-					} catch (XMPPException e) {
-						System.err.println("Probably lost the connection");
-						e.printStackTrace();
-					}
-				}
+    }
 
-				@Override
-				public void sessionDeclined(final String reason,
-						final JingleSession jingleSession) {
-					System.out.println("Session "
-							+ jingleSession.getResponder()
-							+ "declined because " + reason);
-				}
-
-				@Override
-				public void sessionClosedOnError(final XMPPException e,
-						final JingleSession jingleSession) {
-					System.out
-							.println("Session " + jingleSession.getResponder()
-									+ " closed on error");
-
-				}
-
-				@Override
-				public void sessionClosed(final String reason,
-						final JingleSession jingleSession) {
-					System.out.println("Session "
-							+ jingleSession.getResponder() + "closed because "
-							+ reason);
-				}
-			});
-			out.startOutgoing();
+    private void initialize() {
+	mediaManagers = new ArrayList<JingleMediaManager>();
+	mediaManagers.add(new SenderMediaManager(new BasicTransportManager()));
+	JingleManager.setJingleServiceEnabled();
+	jingleManager = new JingleManager(con, mediaManagers);
 
-		} catch (XMPPException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-
-	}
-
-	private void initialize() {
-		mediaManagers = new ArrayList<JingleMediaManager>();
-		mediaManagers.add(new SenderMediaManager(new BasicTransportManager()));
-		JingleManager.setJingleServiceEnabled();
-		jingleManager = new JingleManager(con, mediaManagers);
-
-	}
-
-	/**
-	 * @param args
-	 *            Program args
-	 * @throws InterruptedException
-	 *             exception
-	 */
-	public static void main(final String[] args) throws InterruptedException {
-		if (args.length < 3) {
-			System.err.println("Not enough parameters");
-			System.err.println("Usage : Caller user password server jidtocall");
-		}
-		Caller test = new Caller(args[0], args[1], args[2]);
-		test.call("test2@nikita-rack/TEST");
-		Thread.sleep(60000);
-	}
+    }
 
 }
--- a/src/com/beem/project/beem/jingle/FileSender.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/FileSender.java	Fri May 29 20:34:30 2009 +0200
@@ -7,25 +7,33 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
 public class FileSender extends Thread {
-    private int port;
-    private boolean started = false;
-    private String filename;
+
+    public static void main(String args[]) throws InterruptedException, UnknownHostException {
+	FileSender fs = new FileSender("127.0.0.1", 4242, "/tmp/img.jpeg");
+	fs.start();
+	fs.join();
+    }
+
+    private int         port;
+    private boolean     started = false;
+    private String      filename;
+
     private InetAddress local_addr;
 
-    public FileSender(String listenAddr,  int port, String file) throws UnknownHostException{
+    public FileSender(String listenAddr, int port, String file) throws UnknownHostException {
 	this.port = port;
 	this.filename = file;
 	this.local_addr = InetAddress.getByName(listenAddr);
     }
 
-    public void run(){
+    @Override
+    public void run() {
 	try {
 	    ServerSocket ssock = new ServerSocket(port, 50, local_addr);
 	    InputStream in = new BufferedInputStream(new FileInputStream(filename));
@@ -37,7 +45,7 @@
 		started = true;
 		byte buf[] = new byte[1024];
 		int nbbytes = 1;
-		while (started){
+		while (started) {
 		    nbbytes = in.read(buf, 0, 1024);
 		    if (nbbytes == -1)
 			break;
@@ -54,21 +62,15 @@
 		if (ssock != null)
 		    ssock.close();
 	    }
-	} catch (FileNotFoundException e){
-	    System.err.println("Impossible d'ouvrir " + filename +" " + e.getLocalizedMessage());
+	} catch (FileNotFoundException e) {
+	    System.err.println("Impossible d'ouvrir " + filename + " " + e.getLocalizedMessage());
 	} catch (IOException e) {
 	    System.err.println("I/O Error " + e.getLocalizedMessage());
 	}
     }
 
-    public void setStarted(){
+    public void setStarted() {
 	started = false;
     }
 
-    public static void main(String args[]) throws InterruptedException, UnknownHostException {
-	FileSender fs = new FileSender("127.0.0.1" ,4242, "/tmp/img.jpeg");
-	fs.start();
-	fs.join();
-    }
-
 }
--- a/src/com/beem/project/beem/jingle/RTPMediaManager.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/RTPMediaManager.java	Fri May 29 20:34:30 2009 +0200
@@ -12,42 +12,42 @@
 import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
 
 public class RTPMediaManager extends JingleMediaManager {
-	
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(RTPMediaManager.class);
+
+    private static final SmackLogger LOGGER     = SmackLogger.getLogger(RTPMediaManager.class);
 
-	public static final String MEDIA_NAME = "RTP_BIDON";
-	
-	private List<PayloadType> payloads;
+    public static final String       MEDIA_NAME = "RTP_BIDON";
+
+    private List<PayloadType>        payloads;
 
-	public RTPMediaManager(JingleTransportManager transportManager) {
-		super(transportManager);
-		// TODO Auto-generated constructor stub
-		setupPayloads();
-		LOGGER.info("A TestMedia Manager is created(Receiver)");
-	}
+    public RTPMediaManager(JingleTransportManager transportManager) {
+	super(transportManager);
+	// TODO Auto-generated constructor stub
+	setupPayloads();
+	LOGGER.info("A TestMedia Manager is created(Receiver)");
+    }
 
-	@Override
-	public JingleMediaSession createMediaSession(PayloadType payloadType,
-			TransportCandidate remote, TransportCandidate local,
-			JingleSession jingleSession) {
-		// TODO Auto-generated method stub
-		return new RTPMediaSession(payloadType, remote, local, null, jingleSession);
-	}
+    @Override
+    public JingleMediaSession createMediaSession(PayloadType payloadType, TransportCandidate remote,
+	    TransportCandidate local, JingleSession jingleSession) {
+	// TODO Auto-generated method stub
+	return new RTPMediaSession(payloadType, remote, local, null, jingleSession);
+    }
+
+    @Override
+    public String getName() {
+	return MEDIA_NAME;
+    }
 
-	@Override
-	public List<PayloadType> getPayloads() {
-		// TODO Auto-generated method stub
-		return payloads;
-	}
+    @Override
+    public List<PayloadType> getPayloads() {
+	// TODO Auto-generated method stub
+	return payloads;
+    }
 
-	private void setupPayloads() {
-		payloads = new ArrayList<PayloadType>();
-		payloads.add(new PayloadType.Audio(51, "BIDON1"));
-		payloads.add(new PayloadType.Audio(52, "BIDON2"));
-		payloads.add(new PayloadType.Audio(53, "BIDON3"));
-	}
-	
-	public String getName() {
-		return MEDIA_NAME;
-	}
+    private void setupPayloads() {
+	payloads = new ArrayList<PayloadType>();
+	payloads.add(new PayloadType.Audio(51, "BIDON1"));
+	payloads.add(new PayloadType.Audio(52, "BIDON2"));
+	payloads.add(new PayloadType.Audio(53, "BIDON3"));
+    }
 }
--- a/src/com/beem/project/beem/jingle/RTPMediaSession.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/RTPMediaSession.java	Fri May 29 20:34:30 2009 +0200
@@ -11,66 +11,62 @@
 
 /**
  * @author darisk
- * 
  */
 public class RTPMediaSession extends JingleMediaSession {
 
-	private static final SmackLogger LOGGER = SmackLogger
-	.getLogger(RTPMediaSession.class);
-	private RTPTransmitter transmitter;
-	private RTPReceiver receiver;
+    private static final SmackLogger LOGGER = SmackLogger.getLogger(RTPMediaSession.class);
+    private RTPTransmitter           transmitter;
+    private RTPReceiver              receiver;
+
+    /**
+     * @param payloadType
+     * @param remote
+     * @param local
+     * @param mediaLocator
+     * @param jingleSession
+     */
+    public RTPMediaSession(PayloadType payloadType, TransportCandidate remote, TransportCandidate local,
+	    String mediaLocator, JingleSession jingleSession) {
+
+	super(payloadType, remote, local, mediaLocator, jingleSession);
+	initialize();
+	LOGGER.info("Demarrage d'une session avec local: " + local + " #remote: " + remote);
+
+	transmitter = new RTPTransmitter(remote.getIp(), getRemote().getPort());
+	receiver = new RTPReceiver(getLocal().getPort());
+    }
 
-	/**
-	 * @param payloadType
-	 * @param remote
-	 * @param local
-	 * @param mediaLocator
-	 * @param jingleSession
-	 */
-	public RTPMediaSession(PayloadType payloadType,
-			TransportCandidate remote, TransportCandidate local,
-			String mediaLocator, JingleSession jingleSession) {
+    @Override
+    public void initialize() {
+	// TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setTrasmit(boolean active) {
+    }
 
-		super(payloadType, remote, local, mediaLocator, jingleSession);
-		initialize();
-		LOGGER.info("Demarrage d'une session avec local: " + local
-				+ " #remote: " + remote);
+    @Override
+    public void startReceive() {
+
+    }
 
-		transmitter = new RTPTransmitter(remote.getIp(), getRemote().getPort());
-		receiver = new RTPReceiver(getLocal().getPort());
-	}
+    @Override
+    public void startTrasmit() {
+
+    }
 
-	@Override
-	public void initialize() {
-		// TODO Auto-generated method stub
-
+    @Override
+    public void stopReceive() {
+	if (receiver != null) {
+	    receiver.stop();
 	}
-
-	@Override
-	public void setTrasmit(boolean active) {	
-	}
-
-	@Override
-	public void startReceive() {
-
-	}
-
-	@Override
-	public void startTrasmit() {
-
-	}
+    }
 
-	@Override
-	public void stopReceive() {
-		if (receiver != null) {
-			receiver.stop();
-		}
+    @Override
+    public void stopTrasmit() {
+	if (transmitter != null) {
+	    transmitter.stop();
 	}
-
-	@Override
-	public void stopTrasmit() {
-		if (transmitter != null) {
-			transmitter.stop();
-		}
-	}
+    }
 }
--- a/src/com/beem/project/beem/jingle/RTPReceiver.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/RTPReceiver.java	Fri May 29 20:34:30 2009 +0200
@@ -5,93 +5,98 @@
 import java.net.ServerSocket;
 
 import org.jivesoftware.smackx.jingle.SmackLogger;
+import org.jlibrtp.jlibrtp.core.DataFrame;
+import org.jlibrtp.jlibrtp.core.Participant;
+import org.jlibrtp.jlibrtp.core.RTPAppIntf;
+import org.jlibrtp.jlibrtp.core.RTPSession;
 
-import jlibrtp.DataFrame;
-import jlibrtp.Participant;
-import jlibrtp.RTPAppIntf;
-import jlibrtp.RTPSession;
+public class RTPReceiver implements Runnable, RTPAppIntf {
 
-public class RTPReceiver implements Runnable, RTPAppIntf{
+    RTPSession                       rtpSession = null;
+    byte[]                           abData     = null;
+    private boolean                  killme     = false;
+
+    private static final SmackLogger LOGGER     = SmackLogger.getLogger(SenderMediaManager.class);
+
+    public RTPReceiver(int rtpPort) {
+	DatagramSocket rtpSocket = null;
 
-	RTPSession rtpSession = null;
-	byte[] abData = null;
-	private boolean killme = false;
+	try {
+	    rtpSocket = new DatagramSocket(rtpPort);
+	} catch (Exception e) {
+	    System.out.println("RTPSession failed to obtain port");
+	    return;
+	}
+	rtpSession = new RTPSession(rtpSocket, null);
+	rtpSession.naivePktReception(true);
+	rtpSession.RTPSessionRegister(this, null, null);
+    }
 
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(SenderMediaManager.class);
+    @Override
+    public int frameSize(int payloadType) {
+	return 1;
+    }
 
-	public RTPReceiver(int rtpPort) {
-		DatagramSocket rtpSocket = null;
+    protected int getFreePort() {
+	ServerSocket ss;
+	int freePort = 0;
 
-		try {
-			rtpSocket = new DatagramSocket(rtpPort);
-		} catch (Exception e) {
-			System.out.println("RTPSession failed to obtain port");
-			return;
-		}
-		rtpSession = new RTPSession(rtpSocket, null);
-		rtpSession.naivePktReception(true);
-		rtpSession.RTPSessionRegister(this, null, null);
+	for (int i = 0; i < 10; i++) {
+	    freePort = (int) (10000 + Math.round(Math.random() * 10000));
+	    freePort = freePort % 2 == 0 ? freePort : freePort + 1;
+	    try {
+		ss = new ServerSocket(freePort);
+		freePort = ss.getLocalPort();
+		ss.close();
+		return freePort;
+	    } catch (IOException e) {
+		e.printStackTrace();
+	    }
 	}
+	try {
+	    ss = new ServerSocket(0);
+	    freePort = ss.getLocalPort();
+	    ss.close();
+	} catch (IOException e) {
+	    e.printStackTrace();
+	}
+	return freePort;
+    }
 
-	@Override
-	public void run() {
-		start();		
-	}
+    @Override
+    public void receiveData(DataFrame frame, Participant participant) {
+	// byte[] data = frame.getConcatenatedData();
+    }
 
-	private void start() {
-		LOGGER.info("Debut envoi de donnees par RTPTransmitter");
-		while (!killme) {
-			try { Thread.sleep(1000); } catch(Exception e) { }
-		}
+    @Override
+    public void run() {
+	start();
+    }
 
-		try {Thread.sleep(200);} catch (Exception e) {}
-		this.rtpSession.endSession();
-
+    private void start() {
+	LOGGER.info("Debut envoi de donnees par RTPTransmitter");
+	while (!killme) {
+	    try {
+		Thread.sleep(1000);
+	    } catch (Exception e) {
+	    }
 	}
 
-	@Override
-	public int frameSize(int payloadType) {
-		return 1;
+	try {
+	    Thread.sleep(200);
+	} catch (Exception e) {
 	}
-
-	@Override
-	public void receiveData(DataFrame frame, Participant participant) {
-		//byte[] data = frame.getConcatenatedData();		
-	}
+	this.rtpSession.endSession();
 
-	@Override
-	public void userEvent(int type, Participant[] participant) {
-		//rien
-
-	}
-
-	public void stop() {
-		this.killme  = true;
-	}
+    }
 
-	protected int getFreePort() {
-		ServerSocket ss;
-		int freePort = 0;
+    public void stop() {
+	this.killme = true;
+    }
 
-		for (int i = 0; i < 10; i++) {
-			freePort = (int) (10000 + Math.round(Math.random() * 10000));
-			freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-			try {
-				ss = new ServerSocket(freePort);
-				freePort = ss.getLocalPort();
-				ss.close();
-				return freePort;
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-		try {
-			ss = new ServerSocket(0);
-			freePort = ss.getLocalPort();
-			ss.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return freePort;
-	}
+    @Override
+    public void userEvent(int type, Participant[] participant) {
+	// rien
+
+    }
 }
--- a/src/com/beem/project/beem/jingle/RTPTransmitter.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/RTPTransmitter.java	Fri May 29 20:34:30 2009 +0200
@@ -5,96 +5,97 @@
 import java.net.ServerSocket;
 
 import org.jivesoftware.smackx.jingle.SmackLogger;
-
-import jlibrtp.DataFrame;
-import jlibrtp.Participant;
-import jlibrtp.RTPAppIntf;
-import jlibrtp.RTPSession;
+import org.jlibrtp.jlibrtp.core.DataFrame;
+import org.jlibrtp.jlibrtp.core.Participant;
+import org.jlibrtp.jlibrtp.core.RTPAppIntf;
+import org.jlibrtp.jlibrtp.core.RTPSession;
 
 public class RTPTransmitter implements Runnable, RTPAppIntf {
 
-	private static final SmackLogger LOGGER = SmackLogger
-			.getLogger(SenderMediaManager.class);
-	private RTPSession rtpSession;
-	private boolean killme = false;
+    private static final SmackLogger LOGGER     = SmackLogger.getLogger(SenderMediaManager.class);
+    private RTPSession               rtpSession = null;
+    private boolean                  killme     = false;
+
+    public RTPTransmitter(String remoteIP, int port) {
+
+	DatagramSocket rtpSocket = null;
+	int rtpPort = 0;
 
-	public RTPTransmitter(String remoteIP, int port) {
+	try {
+	    rtpPort = getFreePort();
+	    rtpSocket = new DatagramSocket(rtpPort);
+	} catch (Exception e) {
+	    System.out.println("RTPSession failed to obtain port");
+	    return;
+	}
+	rtpSession = new RTPSession(rtpSocket, null);
+	rtpSession.naivePktReception(true);
+	rtpSession.RTPSessionRegister(this, null, null);
+	rtpSession.addParticipant(new Participant(remoteIP, rtpPort, 0));
+    }
 
-		DatagramSocket rtpSocket = null;
-		int rtpPort = 0;
+    @Override
+    public int frameSize(int payloadType) {
+	return 1;
+    }
+
+    protected int getFreePort() {
+	ServerSocket ss;
+	int freePort = 0;
 
-		try {
-			rtpPort = getFreePort();
-			rtpSocket = new DatagramSocket(rtpPort);
-		} catch (Exception e) {
-			System.out.println("RTPSession failed to obtain port");
-			return;
-		}
-		rtpSession = new RTPSession(rtpSocket, null);
-		rtpSession.naivePktReception(true);
-		rtpSession.RTPSessionRegister(this, null, null);
-		rtpSession.addParticipant(new Participant(remoteIP,rtpPort, 0));
+	for (int i = 0; i < 10; i++) {
+	    freePort = (int) (10000 + Math.round(Math.random() * 10000));
+	    freePort = freePort % 2 == 0 ? freePort : freePort + 1;
+	    try {
+		ss = new ServerSocket(freePort);
+		freePort = ss.getLocalPort();
+		ss.close();
+		return freePort;
+	    } catch (IOException e) {
+		e.printStackTrace();
+	    }
 	}
+	try {
+	    ss = new ServerSocket(0);
+	    freePort = ss.getLocalPort();
+	    ss.close();
+	} catch (IOException e) {
+	    e.printStackTrace();
+	}
+	return freePort;
+    }
 
-	private void start() {
-		LOGGER.info("Debut envoi de donnees par RTPTransmitter");
-		while (!killme) {
-			rtpSession.sendData(null);
-		}
+    @Override
+    public void receiveData(DataFrame frame, Participant participant) {
+	// On envoie uniquement
+    }
 
-		try {Thread.sleep(200);} catch (Exception e) {}
-		this.rtpSession.endSession();
-	}
+    @Override
+    public void run() {
+	start();
+    }
 
-	@Override
-	public void run() {
-		start();
-	}
-
-	@Override
-	public int frameSize(int payloadType) {
-		return 1;
+    private void start() {
+	LOGGER.info("Debut envoi de donnees par RTPTransmitter");
+	while (!killme) {
+	    rtpSession.sendData(null);
 	}
 
-	@Override
-	public void receiveData(DataFrame frame, Participant participant) {
-		//On envoie uniquement
+	try {
+	    Thread.sleep(200);
+	} catch (Exception e) {
 	}
-
-	@Override
-	public void userEvent(int type, Participant[] participant) {
-		//je sais pas ce que c'est
-
-	}
-
-	protected int getFreePort() {
-		ServerSocket ss;
-		int freePort = 0;
+	this.rtpSession.endSession();
+    }
 
-		for (int i = 0; i < 10; i++) {
-			freePort = (int) (10000 + Math.round(Math.random() * 10000));
-			freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-			try {
-				ss = new ServerSocket(freePort);
-				freePort = ss.getLocalPort();
-				ss.close();
-				return freePort;
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-		try {
-			ss = new ServerSocket(0);
-			freePort = ss.getLocalPort();
-			ss.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return freePort;
-	}
+    public void stop() {
+	this.killme = true;
+    }
 
-	public void stop() {
-		this.killme = true;
-	}
+    @Override
+    public void userEvent(int type, Participant[] participant) {
+	// je sais pas ce que c'est
+
+    }
 
 }
--- a/src/com/beem/project/beem/jingle/Receiver.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/Receiver.java	Fri May 29 20:34:30 2009 +0200
@@ -5,6 +5,7 @@
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.jivesoftware.smack.ConnectionConfiguration;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
@@ -19,39 +20,54 @@
 import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
 import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
 
-
 public class Receiver {
 
-    private XMPPConnection con;
-    private JingleManager jingleManager;
+    /**
+     * @param args
+     * @throws InterruptedException
+     * @throws InterruptedException
+     */
+    public static void main(String[] args) throws InterruptedException {
+	@SuppressWarnings("unused")
+	Receiver rec = new Receiver("test2", "test2");
+	System.out.println("Receiver initialized");
+
+	Thread.sleep(60000);
+
+    }
+
+    private XMPPConnection           con;
+    private JingleManager            jingleManager;
     private List<JingleMediaManager> mediaManagers;
-    private JingleSession in;
+
+    private JingleSession            in;
 
     public Receiver(String username, String pass) {
-	//		XMPPConnection.DEBUG_ENABLED = true;
+	// XMPPConnection.DEBUG_ENABLED = true;
 	ConnectionConfiguration conf = new ConnectionConfiguration("nikita-rack");
 	conf.setRosterLoadedAtLogin(false);
 	con = new XMPPConnection(conf);
-	
+
 	try {
-		
+
 	    con.connect();
 	    JingleManager.setJingleServiceEnabled();
-		ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(con);
-	    //NOTE  Classe gerant le service discovery (ce qui permet aux autres de savoir ce qu'on sait faire)
-	    
-	    
-	    //Pour rajouter une liste de feature supporter (de format : "http://jabber.org/protocol/disco#info")
+	    ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(con);
+	    // NOTE Classe gerant le service discovery (ce qui permet aux autres de savoir ce qu'on
+	    // sait faire)
+
+	    // Pour rajouter une liste de feature supporter (de format :
+	    // "http://jabber.org/protocol/disco#info")
 	    sdm.addFeature("http://jabber.org/protocol/disco#info");
 	    sdm.addFeature("TOTO");
-	    
+
 	    con.login(username, pass, "TEST-JAVA");
 	    initialize();
 	    // Le client demande les services dispo en face a son roster
 	    // il doit en suite fournir lui meme une liste de feature
-	    
-	    //DiscoverInfo di = sdm.discoverInfo("test@nikita-rack/pidgin");
-	    //DiscoverInfo di2 = sdm.discoverInfo("nikita@nikita-rack/Telepathy");
+
+	    // DiscoverInfo di = sdm.discoverInfo("test@nikita-rack/pidgin");
+	    // DiscoverInfo di2 = sdm.discoverInfo("nikita@nikita-rack/Telepathy");
 
 	} catch (XMPPException e) {
 	    // TODO Auto-generated catch block
@@ -60,62 +76,60 @@
     }
 
     private void initialize() {
-    BasicTransportManager bt = new BasicTransportManager();
+	BasicTransportManager bt = new BasicTransportManager();
 	mediaManagers = new ArrayList<JingleMediaManager>();
 	mediaManagers.add(new RTPMediaManager(bt));
 	mediaManagers.add(new SenderMediaManager(bt));
-	
+
 	jingleManager = new JingleManager(con, mediaManagers);
 	jingleManager.addJingleSessionRequestListener(new JingleSessionRequestListener() {
 
 	    @Override
 	    public void sessionRequested(JingleSessionRequest request) {
-		System.out.println("Jingle Session request from "+request.getFrom());
+		System.out.println("Jingle Session request from " + request.getFrom());
 		try {
 		    in = request.accept();
 		    in.addListener(new JingleSessionListener() {
 
 			@Override
-			public void sessionRedirected(String redirection,
-			    JingleSession jingleSession) {
+			public void sessionClosed(String reason, JingleSession jingleSession) {
+			    System.out.println("Session " + jingleSession.getResponder() + "closedd because " + reason);
+			}
+
+			@Override
+			public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
+			    // TODO Auto-generated method stub
+			    System.out.println("Session " + jingleSession.getResponder() + " closed");
+
 			}
 
 			@Override
-			public void sessionMediaReceived(JingleSession jingleSession,
-			    String participant) {
-			    System.out.println("Session Media received from " + participant);
+			public void sessionDeclined(String reason, JingleSession jingleSession) {
+			    // TODO Auto-generated method stub
+			    System.out
+				    .println("Session " + jingleSession.getResponder() + "declined because " + reason);
 			}
 
 			@Override
-			public void sessionEstablished(PayloadType pt,
-			    TransportCandidate remoteCandidate,
-			    TransportCandidate localCandidate, JingleSession jingleSession) {
+			public void sessionEstablished(PayloadType pt, TransportCandidate remoteCandidate,
+			        TransportCandidate localCandidate, JingleSession jingleSession) {
 			    System.out.println("Session established");
-			    try{
-				System.out.println("Je recois sur " + remoteCandidate.getIp() + ":" + remoteCandidate.getPort() );
+			    try {
+				System.out.println("Je recois sur " + remoteCandidate.getIp() + ":"
+				        + remoteCandidate.getPort());
 				receiveData(remoteCandidate.getIp(), remoteCandidate.getPort());
-			    } catch (IOException e){
+			    } catch (IOException e) {
 				e.printStackTrace();
 			    }
 			}
 
 			@Override
-			public void sessionDeclined(String reason, JingleSession jingleSession) {
-			    // TODO Auto-generated method stub
-			    System.out.println("Session "+ jingleSession.getResponder() +"declined because "+ reason);
+			public void sessionMediaReceived(JingleSession jingleSession, String participant) {
+			    System.out.println("Session Media received from " + participant);
 			}
 
 			@Override
-			public void sessionClosedOnError(XMPPException e,
-				JingleSession jingleSession) {
-			    // TODO Auto-generated method stub
-			    System.out.println("Session "+ jingleSession.getResponder() + " closed"); 
-
-			}
-
-			@Override
-			public void sessionClosed(String reason, JingleSession jingleSession) {
-			    System.out.println("Session "+ jingleSession.getResponder() +"closedd because "+ reason);
+			public void sessionRedirected(String redirection, JingleSession jingleSession) {
 			}
 		    });
 		    in.startIncoming();
@@ -127,15 +141,14 @@
 
     }
 
-
     private void receiveData(String ip, int port) throws IOException {
 	Socket s = null;
 	try {
-	    s = new Socket(ip, port); 
+	    s = new Socket(ip, port);
 	    System.out.println("Waiting data");
 	    InputStream in = s.getInputStream();
 	    int a;
-	    while ( (a = in.read()) != -1) {
+	    while ((a = in.read()) != -1) {
 		System.out.println("Received " + a);
 	    }
 	    System.out.println("End receiving data");
@@ -145,17 +158,4 @@
 	}
     }
 
-    /**
-     * @param args
-     * @throws InterruptedException 
-     * @throws InterruptedException 
-     */
-    public static void main(String[] args) throws InterruptedException {
-	Receiver rec = new Receiver("test2", "test2");
-	System.out.println("Receiver initialized");
-
-	Thread.sleep(60000);
-
-    }
-
 }
--- a/src/com/beem/project/beem/jingle/ReceiverMediaManager.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/ReceiverMediaManager.java	Fri May 29 20:34:30 2009 +0200
@@ -13,41 +13,41 @@
 import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
 
 public class ReceiverMediaManager extends JingleMediaManager {
-	
-	private static final SmackLogger LOGGER = SmackLogger.getLogger(ReceiverMediaManager.class);
+
+    private static final SmackLogger LOGGER     = SmackLogger.getLogger(ReceiverMediaManager.class);
 
-	public static final String MEDIA_NAME = "69Test";
-	
-	private List<PayloadType> payloads;
+    public static final String       MEDIA_NAME = "69Test";
+
+    private List<PayloadType>        payloads;
 
-	public ReceiverMediaManager(JingleTransportManager transportManager) {
-		super(transportManager);
-		// TODO Auto-generated constructor stub
-		setupPayloads();
-		LOGGER.info("A TestMedia Manager is created");
-	}
+    public ReceiverMediaManager(JingleTransportManager transportManager) {
+	super(transportManager);
+	// TODO Auto-generated constructor stub
+	setupPayloads();
+	LOGGER.info("A TestMedia Manager is created");
+    }
 
-	@Override
-	public JingleMediaSession createMediaSession(PayloadType payloadType,
-			TransportCandidate remote, TransportCandidate local,
-			JingleSession jingleSession) {
-		// TODO Auto-generated method stub
-		return new TestMediaSession(payloadType, remote, local, null, jingleSession);
-	}
+    @Override
+    public JingleMediaSession createMediaSession(PayloadType payloadType, TransportCandidate remote,
+	    TransportCandidate local, JingleSession jingleSession) {
+	// TODO Auto-generated method stub
+	return new TestMediaSession(payloadType, remote, local, null, jingleSession);
+    }
+
+    @Override
+    public String getName() {
+	return MEDIA_NAME;
+    }
 
-	@Override
-	public List<PayloadType> getPayloads() {
-		// TODO Auto-generated method stub
-		return payloads;
-	}
+    @Override
+    public List<PayloadType> getPayloads() {
+	// TODO Auto-generated method stub
+	return payloads;
+    }
 
-	private void setupPayloads() {
-		payloads = new ArrayList<PayloadType>();
-		payloads.add(new PayloadType.Audio(42, "Test"));
-		payloads.add(new PayloadType.Audio(69, "Test2"));
-	}
-	
-	public String getName() {
-		return MEDIA_NAME;
-	}
+    private void setupPayloads() {
+	payloads = new ArrayList<PayloadType>();
+	payloads.add(new PayloadType.Audio(42, "Test"));
+	payloads.add(new PayloadType.Audio(69, "Test2"));
+    }
 }
--- a/src/com/beem/project/beem/jingle/SenderMediaManager.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/SenderMediaManager.java	Fri May 29 20:34:30 2009 +0200
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+
 import org.jivesoftware.smackx.jingle.JingleSession;
 import org.jivesoftware.smackx.jingle.SmackLogger;
 import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
@@ -12,42 +13,39 @@
 
 public class SenderMediaManager extends JingleMediaManager {
 
-	private static final SmackLogger LOGGER = SmackLogger
-			.getLogger(SenderMediaManager.class);
+    private static final SmackLogger LOGGER     = SmackLogger.getLogger(SenderMediaManager.class);
 
-	public static final String MEDIA_NAME = "42Test";
+    public static final String       MEDIA_NAME = "42Test";
 
-	private List<PayloadType> payloads;
+    private List<PayloadType>        payloads;
 
-	public SenderMediaManager(JingleTransportManager transportManager) {
-		super(transportManager);
-		// TODO Auto-generated constructor stub
-		setupPayloads();
-		LOGGER.info("A TestMedia Manager is created(Sender)");
-	}
+    public SenderMediaManager(JingleTransportManager transportManager) {
+	super(transportManager);
+	// TODO Auto-generated constructor stub
+	setupPayloads();
+	LOGGER.info("A TestMedia Manager is created(Sender)");
+    }
 
-	@Override
-	public JingleMediaSession createMediaSession(PayloadType payloadType,
-			TransportCandidate remote, TransportCandidate local,
-			JingleSession jingleSession) {
-		// TODO Auto-generated method stub
-		return new RTPMediaSession(payloadType, remote, local, null,
-				jingleSession);
-	}
+    @Override
+    public JingleMediaSession createMediaSession(PayloadType payloadType, TransportCandidate remote,
+	    TransportCandidate local, JingleSession jingleSession) {
+	// TODO Auto-generated method stub
+	return new RTPMediaSession(payloadType, remote, local, null, jingleSession);
+    }
+
+    @Override
+    public String getName() {
+	return MEDIA_NAME;
+    }
 
-	@Override
-	public List<PayloadType> getPayloads() {
-		return payloads;
-	}
+    @Override
+    public List<PayloadType> getPayloads() {
+	return payloads;
+    }
 
-	private void setupPayloads() {
-		payloads = new ArrayList<PayloadType>();
-		payloads.add(new PayloadType.Audio(42, "Test"));
-		payloads.add(new PayloadType.Audio(15, "Speex"));
-	}
-
-	@Override
-	public String getName() {
-		return MEDIA_NAME;
-	}
+    private void setupPayloads() {
+	payloads = new ArrayList<PayloadType>();
+	payloads.add(new PayloadType.Audio(42, "Test"));
+	payloads.add(new PayloadType.Audio(15, "Speex"));
+    }
 }
--- a/src/com/beem/project/beem/jingle/SenderMediaSession.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/jingle/SenderMediaSession.java	Fri May 29 20:34:30 2009 +0200
@@ -11,14 +11,16 @@
 
 /**
  * @author darisk
- *
  */
 public class SenderMediaSession extends JingleMediaSession {
 
-    private static final SmackLogger LOGGER = SmackLogger.getLogger(SenderMediaSession.class);
-    private boolean active = false;
-    private boolean started = false;
-    private FileSender fileSender;
+    private static final SmackLogger LOGGER  = SmackLogger.getLogger(SenderMediaSession.class);
+    @SuppressWarnings("unused")
+    private boolean                  active  = false;
+    @SuppressWarnings("unused")
+    private boolean                  started = false;
+    @SuppressWarnings("unused")
+    private FileSender               fileSender;
 
     /**
      * @param payloadType
@@ -27,22 +29,25 @@
      * @param mediaLocator
      * @param jingleSession
      */
-    public SenderMediaSession(PayloadType payloadType, TransportCandidate remote,
-	    TransportCandidate local, String mediaLocator,
-	    JingleSession jingleSession) {
+    public SenderMediaSession(PayloadType payloadType, TransportCandidate remote, TransportCandidate local,
+	    String mediaLocator, JingleSession jingleSession) {
 	super(payloadType, remote, local, mediaLocator, jingleSession);
 	initialize();
-	LOGGER.info("Demarrage d'une session avec local: "+ local +" #remote: "+remote );
+	LOGGER.info("Demarrage d'une session avec local: " + local + " #remote: " + remote);
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#initialize()
      */
     @Override
     public void initialize() {
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#setTrasmit(boolean)
      */
     @Override
@@ -51,7 +56,9 @@
 	this.active = active;
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#startReceive()
      */
     @Override
@@ -60,14 +67,18 @@
 
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#startTrasmit()
      */
     @Override
     public void startTrasmit() {
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#stopReceive()
      */
     @Override
@@ -76,7 +87,9 @@
 
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     * 
      * @see org.jivesoftware.smackx.jingle.media.JingleMediaSession#stopTrasmit()
      */
     @Override
@@ -85,6 +98,4 @@
 	started = false;
     }
 
-
-
 }
--- a/src/com/beem/project/beem/provider/Beem.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/provider/Beem.java	Fri May 29 20:34:30 2009 +0200
@@ -8,150 +8,162 @@
  */
 public final class Beem {
 
-	public final static String 	AUTHORITY = "com.beem.project.provider";
+    /**
+     * Contacts table
+     */
+    public static final class Contacts implements BaseColumns {
 
-	public final static String	DB_NAME = "beem.db";
-	public final static int		DB_VERSION = 2;
-
-	public final static String	USERS_TABLE_NAME = "users";
-	public final static String	CONTACTS_TABLE_NAME = "contacts";
+	/**
+	 * The query used to create the table
+	 */
+	public final static String QUERY_CREATE       = "CREATE TABLE " + Beem.CONTACTS_TABLE_NAME + " ("
+	                                                      + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+	                                                      + Contacts.UID + " INTEGER, " + Contacts.JID
+	                                                      + " INTEGER," + Contacts.NICKNAME + " TEXT,"
+	                                                      + Contacts.ALIAS + " TEXT," + Contacts.DATE_CREATED
+	                                                      + " INTEGER," + Contacts.DATE_MODIFIED + " INTEGER"
+	                                                      + ");";
 
 	/**
-	 * Constructor
+	 * The content:// style URL for Contacts table
+	 */
+	public final static Uri    CONTENT_URI        = Uri.parse("content://" + AUTHORITY + "/contacts");
+
+	/**
+	 * The MIME type of {@link #CONTENT_URI} providing a directory of contacts.
 	 */
-	private Beem() {}
+	public static final String CONTENT_TYPE       = "vnd.android.cursor.dir/vnd.beem.project.contact";
 
+	/**
+	 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single contact.
+	 */
+	public static final String CONTENT_ITEM_TYPE  = "vnd.android.cursor.item/vnd.beem.project.contact";
+
+	/**
+	 * The default sort order for this table
+	 */
+	public final static String DEFAULT_SORT_ORDER = "nickname ASC";
 
 	/**
-	 * Users table
+	 * The user id having the contact
+	 * <P>
+	 * Type: INTEGER
+	 * </P>
 	 */
-	public static final class Users implements BaseColumns {
-		
-		/**
-		 * The query used to create the table
-		 */
-		public final static String	QUERY_CREATE = 
-			"CREATE TABLE " + Beem.USERS_TABLE_NAME + " ("
-			+ Users._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
-			+ Users.JUSERNAME + " TEXT,"
-			+ Users.DATE_CREATED + " INTEGER,"
-			+ Users.DATE_MODIFIED + " INTEGER"
-			+ ");";
-		
-		/**
-		 * The content:// style URL for Contacts table
-		 */
-		public final static Uri		CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/users");
+	public final static String UID                = "uid";
 
-		/**
-		 * The MIME type of {@link #CONTENT_URI} providing a directory of users.
-		 */
-		public static final String	CONTENT_TYPE = "vnd.android.cursor.dir/vnd.beem.project.user";
+	/**
+	 * The JabberID of the contact
+	 * <P>
+	 * Type: INTEGER
+	 * </P>
+	 */
+	public final static String JID                = "jid";
 
-		/**
-		 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single user.
-		 */
-		public static final String	CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.beem.project.user";
-
-		/**
-		 * The default sort order for this table
-		 */
-		public final static String 	DEFAULT_SORT_ORDER = "_id ASC";
+	/**
+	 * The nickname of the contact
+	 * <P>
+	 * Type: TEXT
+	 * </P>
+	 */
+	public final static String NICKNAME           = "nickname";
 
-		/**
-		 * The Jabber username of the user
-		 * <P>Type: TEXT</P>
-		 */
-		public final static String	JUSERNAME = "username";
-		
-		/**
-		 * The timestamp for when the user was created
-		 * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
-		 */
-		public final static String	DATE_CREATED = "created";
+	/**
+	 * The alias of the contact
+	 * <P>
+	 * Type: TEXT
+	 * </P>
+	 */
+	public final static String ALIAS              = "alias";
 
-		/**
-		 * The timestamp for when the user was last modified
-		 * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
-		 */
-		public final static String	DATE_MODIFIED = "modified";
-	}
-
+	/**
+	 * The timestamp for when the contact was created
+	 * <P>
+	 * Type: INTEGER (long from System.curentTimeMillis())
+	 * </P>
+	 */
+	public final static String DATE_CREATED       = "created";
 
 	/**
-	 * Contacts table
+	 * The timestamp for when the contact was last modified
+	 * <P>
+	 * Type: INTEGER (long from System.curentTimeMillis())
+	 * </P>
 	 */
-	public static final class Contacts implements BaseColumns {
+	public final static String DATE_MODIFIED      = "modified";
 
-		/**
-		 * The query used to create the table
-		 */
-		public final static String	QUERY_CREATE = 
-			"CREATE TABLE " + Beem.CONTACTS_TABLE_NAME + " ("
-			+ Contacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
-			+ Contacts.UID + " INTEGER, "
-			+ Contacts.JID + " INTEGER,"
-			+ Contacts.NICKNAME + " TEXT,"
-			+ Contacts.ALIAS + " TEXT,"
-			+ Contacts.DATE_CREATED + " INTEGER,"
-			+ Contacts.DATE_MODIFIED + " INTEGER"
-			+ ");";
+    }
+
+    /**
+     * Users table
+     */
+    public static final class Users implements BaseColumns {
 
-		/**
-		 * The content:// style URL for Contacts table
-		 */
-		public final static Uri		CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/contacts");
-
-		/**
-		 * The MIME type of {@link #CONTENT_URI} providing a directory of contacts.
-		 */
-		public static final String	CONTENT_TYPE = "vnd.android.cursor.dir/vnd.beem.project.contact";
+	/**
+	 * The query used to create the table
+	 */
+	public final static String QUERY_CREATE       = "CREATE TABLE " + Beem.USERS_TABLE_NAME + " ("
+	                                                      + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+	                                                      + Users.JUSERNAME + " TEXT," + Users.DATE_CREATED
+	                                                      + " INTEGER," + Users.DATE_MODIFIED + " INTEGER" + ");";
 
-		/**
-		 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single contact.
-		 */
-		public static final String	CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.beem.project.contact";
+	/**
+	 * The content:// style URL for Contacts table
+	 */
+	public final static Uri    CONTENT_URI        = Uri.parse("content://" + AUTHORITY + "/users");
 
-		/**
-		 * The default sort order for this table
-		 */
-		public final static String 	DEFAULT_SORT_ORDER = "nickname ASC";
+	/**
+	 * The MIME type of {@link #CONTENT_URI} providing a directory of users.
+	 */
+	public static final String CONTENT_TYPE       = "vnd.android.cursor.dir/vnd.beem.project.user";
+
+	/**
+	 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single user.
+	 */
+	public static final String CONTENT_ITEM_TYPE  = "vnd.android.cursor.item/vnd.beem.project.user";
 
-		/**
-		 * The user id having the contact
-		 * <P>Type: INTEGER</P>
-		 */
-		public final static String	UID = "uid";
+	/**
+	 * The default sort order for this table
+	 */
+	public final static String DEFAULT_SORT_ORDER = "_id ASC";
 
-		/**
-		 * The JabberID of the contact
-		 * <P>Type: INTEGER</P>
-		 */
-		public final static String	JID = "jid";
+	/**
+	 * The Jabber username of the user
+	 * <P>
+	 * Type: TEXT
+	 * </P>
+	 */
+	public final static String JUSERNAME          = "username";
 
-		/**
-		 * The nickname of the contact
-		 * <P>Type: TEXT</P>
-		 */
-		public final static String	NICKNAME = "nickname";
+	/**
+	 * The timestamp for when the user was created
+	 * <P>
+	 * Type: INTEGER (long from System.curentTimeMillis())
+	 * </P>
+	 */
+	public final static String DATE_CREATED       = "created";
 
-		/**
-		 * The alias of the contact
-		 * <P>Type: TEXT</P>
-		 */
-		public final static String	ALIAS = "alias";
+	/**
+	 * The timestamp for when the user was last modified
+	 * <P>
+	 * Type: INTEGER (long from System.curentTimeMillis())
+	 * </P>
+	 */
+	public final static String DATE_MODIFIED      = "modified";
+    }
+
+    public final static String AUTHORITY           = "com.beem.project.provider";
 
-		/**
-		 * The timestamp for when the contact was created
-		 * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
-		 */
-		public final static String	DATE_CREATED = "created";
+    public final static String DB_NAME             = "beem.db";
+    public final static int    DB_VERSION          = 2;
+
+    public final static String USERS_TABLE_NAME    = "users";
+
+    public final static String CONTACTS_TABLE_NAME = "contacts";
 
-		/**
-		 * The timestamp for when the contact was last modified
-		 * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
-		 */
-		public final static String	DATE_MODIFIED = "modified";
-
-	}
+    /**
+     * Constructor
+     */
+    private Beem() {
+    }
 }
--- a/src/com/beem/project/beem/provider/BeemDatabaseHelper.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/provider/BeemDatabaseHelper.java	Fri May 29 20:34:30 2009 +0200
@@ -6,30 +6,29 @@
 import android.util.Log;
 
 public class BeemDatabaseHelper extends SQLiteOpenHelper {
-	
-	private String tag;
-	private String tableName;
-	private String creationQuery;
+
+    private String tag;
+    private String tableName;
+    private String creationQuery;
+
+    public BeemDatabaseHelper(Context context, String tag, String tableName, String creationQuery) {
+	super(context, Beem.DB_NAME, null, Beem.DB_VERSION);
+
+	this.tag = tag;
+	this.tableName = tableName;
+	this.creationQuery = creationQuery;
+    }
 
-	public BeemDatabaseHelper(Context context, String tag, String tableName, String creationQuery) {
-		super(context, Beem.DB_NAME, null, Beem.DB_VERSION);
-		
-		this.tag = tag;
-		this.tableName = tableName;
-		this.creationQuery = creationQuery;
-	}
-	
-	@Override
-	public void onCreate(SQLiteDatabase db) {
-		db.execSQL(this.creationQuery);
-	}
-	
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+	db.execSQL(this.creationQuery);
+    }
 
-	@Override
-	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-		Log.w(this.tag, "Upgrading database from version " + oldVersion + " to "
-				+ newVersion + ", which will destroy all old data");
-		db.execSQL("DROP TABLE IF EXISTS " + this.tableName + ";");
-		onCreate(db);
-	}
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+	Log.w(this.tag, "Upgrading database from version " + oldVersion + " to " + newVersion
+	        + ", which will destroy all old data");
+	db.execSQL("DROP TABLE IF EXISTS " + this.tableName + ";");
+	onCreate(db);
+    }
 }
--- a/src/com/beem/project/beem/provider/ContactProvider.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/provider/ContactProvider.java	Fri May 29 20:34:30 2009 +0200
@@ -14,196 +14,194 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.provider.BaseColumns;
 import android.text.TextUtils;
 
 /**
  * @author dasilvj
- *
  */
 public class ContactProvider extends ContentProvider {
 
-	private final static String				TAG = "ContactProvider";
+    private final static String            TAG        = "ContactProvider";
 
-	private static HashMap<String, String>	sContactsProjectionMap;
-
-	private static final int				CONTACTS = 1;
-	private static final int				CONTACT_ID = 2;
+    private static HashMap<String, String> sContactsProjectionMap;
 
-	private static final UriMatcher			sUriMatcher;
-	private BeemDatabaseHelper				mOpenHelper;
+    private static final int               CONTACTS   = 1;
+    private static final int               CONTACT_ID = 2;
 
-	@Override
-	public int delete(Uri uri, String selection, String[] selectionArgs) {
-		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-		int count;
+    private static final UriMatcher        sUriMatcher;
+    static {
+	sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+	sUriMatcher.addURI(Beem.AUTHORITY, "contacts", CONTACTS);
+	sUriMatcher.addURI(Beem.AUTHORITY, "contacts/#", CONTACT_ID);
 
-		switch (sUriMatcher.match(uri)) {
-		case CONTACTS:
-			count = db.delete(Beem.CONTACTS_TABLE_NAME, selection, selectionArgs);
-			break;
+	sContactsProjectionMap = new HashMap<String, String>();
+	sContactsProjectionMap.put(BaseColumns._ID, BaseColumns._ID);
+	sContactsProjectionMap.put(Beem.Contacts.UID, Beem.Contacts.UID);
+	sContactsProjectionMap.put(Beem.Contacts.JID, Beem.Contacts.JID);
+	sContactsProjectionMap.put(Beem.Contacts.NICKNAME, Beem.Contacts.NICKNAME);
+	sContactsProjectionMap.put(Beem.Contacts.ALIAS, Beem.Contacts.ALIAS);
+	sContactsProjectionMap.put(Beem.Contacts.DATE_CREATED, Beem.Contacts.DATE_CREATED);
+	sContactsProjectionMap.put(Beem.Contacts.DATE_MODIFIED, Beem.Contacts.DATE_MODIFIED);
+    }
+
+    private BeemDatabaseHelper             mOpenHelper;
 
-		case CONTACT_ID:
-			String contactId = uri.getPathSegments().get(1);
-			count = db.delete(Beem.CONTACTS_TABLE_NAME, Beem.Contacts._ID + "=" + contactId
-					+ (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
-			break;
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	int count;
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);
-		}
+	switch (sUriMatcher.match(uri)) {
+	case CONTACTS:
+	    count = db.delete(Beem.CONTACTS_TABLE_NAME, selection, selectionArgs);
+	    break;
 
-		getContext().getContentResolver().notifyChange(uri, null);
-		return count;
+	case CONTACT_ID:
+	    String contactId = uri.getPathSegments().get(1);
+	    count = db.delete(Beem.CONTACTS_TABLE_NAME, BaseColumns._ID + "=" + contactId
+		    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
+	    break;
+
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
 
-	@Override
-	public String getType(Uri uri) {
-		switch (sUriMatcher.match(uri)) {
-		case CONTACTS:
-			return Beem.Contacts.CONTENT_TYPE;
+	getContext().getContentResolver().notifyChange(uri, null);
+	return count;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+	switch (sUriMatcher.match(uri)) {
+	case CONTACTS:
+	    return Beem.Contacts.CONTENT_TYPE;
+
+	case CONTACT_ID:
+	    return Beem.Contacts.CONTENT_ITEM_TYPE;
+
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
+	}
+    }
 
-		case CONTACT_ID:
-			return Beem.Contacts.CONTENT_ITEM_TYPE;
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+	// Validate the requested uri
+	if (sUriMatcher.match(uri) != CONTACTS) {
+	    throw new IllegalArgumentException("Unknown URI " + uri);
+	}
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);
-		}
+	ContentValues values;
+	if (initialValues != null) {
+	    values = new ContentValues(initialValues);
+	} else {
+	    values = new ContentValues();
+	}
+
+	Long now = Long.valueOf(System.currentTimeMillis());
+
+	// Make sure that the fields are all set
+	if (values.containsKey(Beem.Contacts.UID) == false) {
+	    // TODO :: Must check that the UID exists using UserProvider
+	    throw new SQLException("No UID specified. Failed to insert row into " + uri);
+	}
+
+	if (values.containsKey(Beem.Contacts.JID) == false) {
+	    values.put(Beem.Contacts.JID, "");
 	}
 
-	@Override
-	public Uri insert(Uri uri, ContentValues initialValues) {
-        // Validate the requested uri
-        if (sUriMatcher.match(uri) != CONTACTS) {
-            throw new IllegalArgumentException("Unknown URI " + uri);
-        }
-
-        ContentValues values;
-        if (initialValues != null) {
-            values = new ContentValues(initialValues);
-        } else {
-            values = new ContentValues();
-        }
-
-        Long now = Long.valueOf(System.currentTimeMillis());
-
-        // Make sure that the fields are all set
-        if (values.containsKey(Beem.Contacts.UID) == false) {
-        	// TODO :: Must check that the UID exists using UserProvider
-            throw new SQLException("No UID specified. Failed to insert row into " + uri);
-        }
+	if (values.containsKey(Beem.Contacts.NICKNAME) == false) {
+	    values.put(Beem.Contacts.JID, "");
+	}
 
-        if (values.containsKey(Beem.Contacts.JID) == false) {
-            values.put(Beem.Contacts.JID, "");
-        }
-        
-        if (values.containsKey(Beem.Contacts.NICKNAME) == false) {
-            values.put(Beem.Contacts.JID, "");
-        }
-        
-        if (values.containsKey(Beem.Contacts.ALIAS) == false) {
-            values.put(Beem.Contacts.JID, "");
-        }
-        
-        if (values.containsKey(Beem.Contacts.DATE_CREATED) == false) {
-            values.put(Beem.Contacts.DATE_CREATED, now);
-        }
-
-        if (values.containsKey(Beem.Contacts.DATE_MODIFIED) == false) {
-            values.put(Beem.Contacts.DATE_MODIFIED, now);
-        }
-
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        long rowId = db.insert(Beem.CONTACTS_TABLE_NAME, Beem.Contacts._ID, values);
-        if (rowId > 0) {
-            Uri contactUri = ContentUris.withAppendedId(Beem.Contacts.CONTENT_URI, rowId);
-            getContext().getContentResolver().notifyChange(contactUri, null);
-            return contactUri;
-        }
-
-        throw new SQLException("Failed to insert row into " + uri);
+	if (values.containsKey(Beem.Contacts.ALIAS) == false) {
+	    values.put(Beem.Contacts.JID, "");
 	}
 
-	@Override
-	public boolean onCreate() {
-		mOpenHelper = new BeemDatabaseHelper(getContext(), TAG, Beem.CONTACTS_TABLE_NAME, Beem.Contacts.QUERY_CREATE);
-		return true;
+	if (values.containsKey(Beem.Contacts.DATE_CREATED) == false) {
+	    values.put(Beem.Contacts.DATE_CREATED, now);
+	}
+
+	if (values.containsKey(Beem.Contacts.DATE_MODIFIED) == false) {
+	    values.put(Beem.Contacts.DATE_MODIFIED, now);
+	}
+
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	long rowId = db.insert(Beem.CONTACTS_TABLE_NAME, BaseColumns._ID, values);
+	if (rowId > 0) {
+	    Uri contactUri = ContentUris.withAppendedId(Beem.Contacts.CONTENT_URI, rowId);
+	    getContext().getContentResolver().notifyChange(contactUri, null);
+	    return contactUri;
 	}
 
-	@Override
-	public Cursor query(Uri uri, String[] projection, String selection,
-			String[] selectionArgs, String sortOrder) {
-		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+	throw new SQLException("Failed to insert row into " + uri);
+    }
 
-		switch (sUriMatcher.match(uri)) {
-		case CONTACTS:
-			qb.setTables(Beem.CONTACTS_TABLE_NAME);
-			qb.setProjectionMap(sContactsProjectionMap);
-			break;
+    @Override
+    public boolean onCreate() {
+	mOpenHelper = new BeemDatabaseHelper(getContext(), TAG, Beem.CONTACTS_TABLE_NAME, Beem.Contacts.QUERY_CREATE);
+	return true;
+    }
 
-		case CONTACT_ID:
-			qb.setTables(Beem.USERS_TABLE_NAME);
-			qb.setProjectionMap(sContactsProjectionMap);
-			qb.appendWhere(Beem.Contacts._ID + "=" + uri.getPathSegments().get(1));
-			break;
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+	SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);        
-		}
+	switch (sUriMatcher.match(uri)) {
+	case CONTACTS:
+	    qb.setTables(Beem.CONTACTS_TABLE_NAME);
+	    qb.setProjectionMap(sContactsProjectionMap);
+	    break;
 
-		// If no sort order is specified use the default
-		String orderBy;
-		if (TextUtils.isEmpty(sortOrder)) {
-			orderBy = Beem.Contacts.DEFAULT_SORT_ORDER;
-		} else {
-			orderBy = sortOrder;
-		}
+	case CONTACT_ID:
+	    qb.setTables(Beem.USERS_TABLE_NAME);
+	    qb.setProjectionMap(sContactsProjectionMap);
+	    qb.appendWhere(BaseColumns._ID + "=" + uri.getPathSegments().get(1));
+	    break;
 
-		// Get the database and run the query
-		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
-
-		// Tell the cursor what uri to watch, so it knows when its source data changes
-		c.setNotificationUri(getContext().getContentResolver(), uri);
-		return c;
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
 
-	@Override
-	public int update(Uri uri, ContentValues values, String selection,
-			String[] selectionArgs) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        int count;
-        
-        switch (sUriMatcher.match(uri)) {
-        case CONTACTS:
-            count = db.update(Beem.CONTACTS_TABLE_NAME, values, selection, selectionArgs);
-            break;
-
-        case CONTACT_ID:
-            String contactId = uri.getPathSegments().get(1);
-            count = db.update(Beem.CONTACTS_TABLE_NAME, values, Beem.Contacts._ID + "=" + contactId
-                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
-            break;
-
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
-        }
-
-        getContext().getContentResolver().notifyChange(uri, null);
-        return count;
+	// If no sort order is specified use the default
+	String orderBy;
+	if (TextUtils.isEmpty(sortOrder)) {
+	    orderBy = Beem.Contacts.DEFAULT_SORT_ORDER;
+	} else {
+	    orderBy = sortOrder;
 	}
 
-	static {
-		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-		sUriMatcher.addURI(Beem.AUTHORITY, "contacts", CONTACTS);
-		sUriMatcher.addURI(Beem.AUTHORITY, "contacts/#", CONTACT_ID);
+	// Get the database and run the query
+	SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+	Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
+
+	// Tell the cursor what uri to watch, so it knows when its source data changes
+	c.setNotificationUri(getContext().getContentResolver(), uri);
+	return c;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	int count;
 
-		sContactsProjectionMap = new HashMap<String, String>();
-		sContactsProjectionMap.put(Beem.Contacts._ID, Beem.Contacts._ID);
-		sContactsProjectionMap.put(Beem.Contacts.UID, Beem.Contacts.UID);
-		sContactsProjectionMap.put(Beem.Contacts.JID, Beem.Contacts.JID);
-		sContactsProjectionMap.put(Beem.Contacts.NICKNAME, Beem.Contacts.NICKNAME);
-		sContactsProjectionMap.put(Beem.Contacts.ALIAS, Beem.Contacts.ALIAS);
-		sContactsProjectionMap.put(Beem.Contacts.DATE_CREATED, Beem.Contacts.DATE_CREATED);
-		sContactsProjectionMap.put(Beem.Contacts.DATE_MODIFIED, Beem.Contacts.DATE_MODIFIED);
+	switch (sUriMatcher.match(uri)) {
+	case CONTACTS:
+	    count = db.update(Beem.CONTACTS_TABLE_NAME, values, selection, selectionArgs);
+	    break;
+
+	case CONTACT_ID:
+	    String contactId = uri.getPathSegments().get(1);
+	    count = db.update(Beem.CONTACTS_TABLE_NAME, values, BaseColumns._ID + "=" + contactId
+		    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
+	    break;
+
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
+
+	getContext().getContentResolver().notifyChange(uri, null);
+	return count;
+    }
 }
--- a/src/com/beem/project/beem/provider/UserProvider.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/provider/UserProvider.java	Fri May 29 20:34:30 2009 +0200
@@ -11,176 +11,175 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.provider.BaseColumns;
 import android.text.TextUtils;
 
 public class UserProvider extends ContentProvider {
 
-	private final static String				TAG = "UserProvider";
+    private final static String            TAG     = "UserProvider";
 
-	private static HashMap<String, String>	sUsersProjectionMap;
+    private static HashMap<String, String> sUsersProjectionMap;
 
-	private static final int				USERS = 1;
-	private static final int				USER_ID = 2;
+    private static final int               USERS   = 1;
+    private static final int               USER_ID = 2;
 
-	private static final UriMatcher			sUriMatcher;
-	private BeemDatabaseHelper				mOpenHelper;
+    private static final UriMatcher        sUriMatcher;
+    static {
+	sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+	sUriMatcher.addURI(Beem.AUTHORITY, "users", USERS);
+	sUriMatcher.addURI(Beem.AUTHORITY, "users/#", USER_ID);
 
-	@Override
-	public int delete(Uri uri, String selection, String[] selectionArgs) {
-		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-		int count;
+	sUsersProjectionMap = new HashMap<String, String>();
+	sUsersProjectionMap.put(BaseColumns._ID, BaseColumns._ID);
+	sUsersProjectionMap.put(Beem.Users.JUSERNAME, Beem.Users.JUSERNAME);
+	sUsersProjectionMap.put(Beem.Users.DATE_CREATED, Beem.Users.DATE_CREATED);
+	sUsersProjectionMap.put(Beem.Users.DATE_MODIFIED, Beem.Users.DATE_MODIFIED);
+    }
 
-		switch (sUriMatcher.match(uri)) {
-		case USERS:
-			count = db.delete(Beem.USERS_TABLE_NAME, selection, selectionArgs);
-			break;
+    private BeemDatabaseHelper             mOpenHelper;
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	int count;
 
-		case USER_ID:
-			String userID = uri.getPathSegments().get(1);
-			count = db.delete(Beem.USERS_TABLE_NAME, Beem.Users._ID + "=" + userID
-					+ (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
-			break;
+	switch (sUriMatcher.match(uri)) {
+	case USERS:
+	    count = db.delete(Beem.USERS_TABLE_NAME, selection, selectionArgs);
+	    break;
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);
-		}
+	case USER_ID:
+	    String userID = uri.getPathSegments().get(1);
+	    count = db.delete(Beem.USERS_TABLE_NAME, BaseColumns._ID + "=" + userID
+		    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
+	    break;
 
-		getContext().getContentResolver().notifyChange(uri, null);
-		return count;
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
 
-	@Override
-	public String getType(Uri uri) {
-		switch (sUriMatcher.match(uri)) {
-		case USERS:
-			return Beem.Users.CONTENT_TYPE;
+	getContext().getContentResolver().notifyChange(uri, null);
+	return count;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+	switch (sUriMatcher.match(uri)) {
+	case USERS:
+	    return Beem.Users.CONTENT_TYPE;
+
+	case USER_ID:
+	    return Beem.Users.CONTENT_ITEM_TYPE;
+
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
+	}
+    }
 
-		case USER_ID:
-			return Beem.Users.CONTENT_ITEM_TYPE;
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+	// Validate the requested uri
+	if (sUriMatcher.match(uri) != USERS) {
+	    throw new IllegalArgumentException("Unknown URI " + uri);
+	}
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);
-		}
+	ContentValues values;
+	if (initialValues != null) {
+	    values = new ContentValues(initialValues);
+	} else {
+	    values = new ContentValues();
+	}
+
+	Long now = Long.valueOf(System.currentTimeMillis());
+
+	// Make sure that the fields are all set
+	if (values.containsKey(Beem.Users.JUSERNAME) == false) {
+	    throw new SQLException("No JUSERNAME specified. Failed to insert row into " + uri);
 	}
 
-	@Override
-	public Uri insert(Uri uri, ContentValues initialValues) {
-        // Validate the requested uri
-        if (sUriMatcher.match(uri) != USERS) {
-            throw new IllegalArgumentException("Unknown URI " + uri);
-        }
-
-        ContentValues values;
-        if (initialValues != null) {
-            values = new ContentValues(initialValues);
-        } else {
-            values = new ContentValues();
-        }
-
-        Long now = Long.valueOf(System.currentTimeMillis());
-
-        // Make sure that the fields are all set
-        if (values.containsKey(Beem.Users.JUSERNAME) == false) {
-            throw new SQLException("No JUSERNAME specified. Failed to insert row into " + uri);
-        }
-        
-        if (values.containsKey(Beem.Users.DATE_CREATED) == false) {
-            values.put(Beem.Users.DATE_CREATED, now);
-        }
-
-        if (values.containsKey(Beem.Users.DATE_MODIFIED) == false) {
-            values.put(Beem.Users.DATE_MODIFIED, now);
-        }
-
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        long rowId = db.insert(Beem.USERS_TABLE_NAME, Beem.Users._ID, values);
-        if (rowId > 0) {
-            Uri userUri = ContentUris.withAppendedId(Beem.Users.CONTENT_URI, rowId);
-            getContext().getContentResolver().notifyChange(userUri, null);
-            return userUri;
-        }
-
-        throw new SQLException("Failed to insert row into " + uri);
+	if (values.containsKey(Beem.Users.DATE_CREATED) == false) {
+	    values.put(Beem.Users.DATE_CREATED, now);
 	}
 
-	@Override
-	public boolean onCreate() {
-		mOpenHelper = new BeemDatabaseHelper(getContext(), TAG, Beem.USERS_TABLE_NAME, Beem.Users.QUERY_CREATE);
-		return true;
+	if (values.containsKey(Beem.Users.DATE_MODIFIED) == false) {
+	    values.put(Beem.Users.DATE_MODIFIED, now);
+	}
+
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	long rowId = db.insert(Beem.USERS_TABLE_NAME, BaseColumns._ID, values);
+	if (rowId > 0) {
+	    Uri userUri = ContentUris.withAppendedId(Beem.Users.CONTENT_URI, rowId);
+	    getContext().getContentResolver().notifyChange(userUri, null);
+	    return userUri;
 	}
 
-	@Override
-	public Cursor query(Uri uri, String[] projection, String selection,
-			String[] selectionArgs, String sortOrder) {
-		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+	throw new SQLException("Failed to insert row into " + uri);
+    }
 
-		switch (sUriMatcher.match(uri)) {
-		case USERS:
-			qb.setTables(Beem.USERS_TABLE_NAME);
-			qb.setProjectionMap(sUsersProjectionMap);
-			break;
+    @Override
+    public boolean onCreate() {
+	mOpenHelper = new BeemDatabaseHelper(getContext(), TAG, Beem.USERS_TABLE_NAME, Beem.Users.QUERY_CREATE);
+	return true;
+    }
 
-		case USER_ID:
-			qb.setTables(Beem.USERS_TABLE_NAME);
-			qb.setProjectionMap(sUsersProjectionMap);
-			qb.appendWhere(Beem.Users._ID + "=" + uri.getPathSegments().get(1));
-			break;
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+	SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
 
-		default:
-			throw new IllegalArgumentException("Unknown URI " + uri);        
-		}
+	switch (sUriMatcher.match(uri)) {
+	case USERS:
+	    qb.setTables(Beem.USERS_TABLE_NAME);
+	    qb.setProjectionMap(sUsersProjectionMap);
+	    break;
 
-		// If no sort order is specified use the default
-		String orderBy;
-		if (TextUtils.isEmpty(sortOrder)) {
-			orderBy = Beem.Users.DEFAULT_SORT_ORDER;
-		} else {
-			orderBy = sortOrder;
-		}
+	case USER_ID:
+	    qb.setTables(Beem.USERS_TABLE_NAME);
+	    qb.setProjectionMap(sUsersProjectionMap);
+	    qb.appendWhere(BaseColumns._ID + "=" + uri.getPathSegments().get(1));
+	    break;
 
-		// Get the database and run the query
-		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
-
-		// Tell the cursor what uri to watch, so it knows when its source data changes
-		c.setNotificationUri(getContext().getContentResolver(), uri);
-		return c;
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
 
-	@Override
-	public int update(Uri uri, ContentValues values, String selection,
-			String[] selectionArgs) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        int count;
-        
-        switch (sUriMatcher.match(uri)) {
-        case USERS:
-            count = db.update(Beem.USERS_TABLE_NAME, values, selection, selectionArgs);
-            break;
-
-        case USER_ID:
-            String userId = uri.getPathSegments().get(1);
-            count = db.update(Beem.USERS_TABLE_NAME, values, Beem.Users._ID + "=" + userId
-                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
-            break;
-
-        default:
-            throw new IllegalArgumentException("Unknown URI " + uri);
-        }
-
-        getContext().getContentResolver().notifyChange(uri, null);
-        return count;
+	// If no sort order is specified use the default
+	String orderBy;
+	if (TextUtils.isEmpty(sortOrder)) {
+	    orderBy = Beem.Users.DEFAULT_SORT_ORDER;
+	} else {
+	    orderBy = sortOrder;
 	}
 
-	static {
-		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-		sUriMatcher.addURI(Beem.AUTHORITY, "users", USERS);
-		sUriMatcher.addURI(Beem.AUTHORITY, "users/#", USER_ID);
+	// Get the database and run the query
+	SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+	Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
+
+	// Tell the cursor what uri to watch, so it knows when its source data changes
+	c.setNotificationUri(getContext().getContentResolver(), uri);
+	return c;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+	SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+	int count;
 
-		sUsersProjectionMap = new HashMap<String, String>();
-		sUsersProjectionMap.put(Beem.Users._ID, Beem.Users._ID);
-		sUsersProjectionMap.put(Beem.Users.JUSERNAME, Beem.Users.JUSERNAME);
-		sUsersProjectionMap.put(Beem.Users.DATE_CREATED, Beem.Users.DATE_CREATED);
-		sUsersProjectionMap.put(Beem.Users.DATE_MODIFIED, Beem.Users.DATE_MODIFIED);
+	switch (sUriMatcher.match(uri)) {
+	case USERS:
+	    count = db.update(Beem.USERS_TABLE_NAME, values, selection, selectionArgs);
+	    break;
+
+	case USER_ID:
+	    String userId = uri.getPathSegments().get(1);
+	    count = db.update(Beem.USERS_TABLE_NAME, values, BaseColumns._ID + "=" + userId
+		    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
+	    break;
+
+	default:
+	    throw new IllegalArgumentException("Unknown URI " + uri);
 	}
+
+	getContext().getContentResolver().notifyChange(uri, null);
+	return count;
+    }
 }
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Fri May 29 20:34:30 2009 +0200
@@ -32,105 +32,14 @@
 
 /**
  * An adapter for smack's ChatManager. This class provides functionnality to handle chats.
+ * 
  * @author darisk
  */
 public class BeemChatManager extends IChatManager.Stub {
 
     /**
-     * Tag to use with log methods.
-     */
-    public static final String TAG = "BeemChatManager";
-    private ChatManager mAdaptee;
-    private Map<String, ChatAdapter> mChats = new HashMap<String, ChatAdapter>();
-    private ChatListener mChatListener = new ChatListener();
-    private RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
-    private RemoteCallbackList<IMessageListener> mRemoteMessageListeners = new RemoteCallbackList<IMessageListener>();
-    private BeemService mService;
-
-    /**
-     * Constructor.
-     * @param chatManager the smack ChatManager to adapt
-     * @param service the service which runs the chat manager
-     */
-    public BeemChatManager(final ChatManager chatManager, final BeemService service) {
-	mService = service;
-	mAdaptee = chatManager;
-	mAdaptee.addChatListener(mChatListener);
-    }
-
-    /**
-     * Create a chat session.
-     * @param jid the jid of the contact you want to chat with
-     * @param listener listener to use for chat events on this chat session
-     * @return the chat session
-     */
-    public IChat createChat(String jid, IMessageListener listener) {
-	mRemoteMessageListeners.register(listener);
-	String key = StringUtils.parseBareAddress(jid);
-	if (mChats.containsKey(key)) {
-	    return mChats.get(key);
-	}
-	// create the chat. the adaptee will be add automatically in the map
-	mAdaptee.createChat(key, mChatListener);
-	return mChats.get(key);
-    }
-
-    /**
-     * Create a chat session.
-     * @param contact the contact you want to chat with
-     * @param listener listener to use for chat events on this chat session
-     * @return the chat session
-     */
-    public IChat createChat(Contact contact, IMessageListener listener) {
-	String jid = contact.getJID();
-	return createChat(jid, listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.register(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.unregister(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void destroyChat(IChat chat) throws RemoteException {
-	// TODO gerer les resources egalement
-	Log.d(TAG, "destroy chat jid " + chat.getParticipant().getJID());
-	IChat c = mChats.remove(chat.getParticipant().getJID());
-	if (c == null)
-	    Log.w(TAG, "CA devrait pas 1!!" + chat.getParticipant().getJID());
-    }
-
-    /**
-     * Get an existing ChatAdapter or create it if necessary.
-     * @param chat The real instance of smack chat
-     * @return a chat adapter register in the manager
-     */
-    private ChatAdapter getChat(Chat chat) {
-	String key = StringUtils.parseBareAddress(chat.getParticipant());
-	if (mChats.containsKey(key)) {
-	    return mChats.get(key);
-	}
-	ChatAdapter res = new ChatAdapter(chat);
-	mChats.put(key, res);
-	return res;
-    }
-
-    /**
      * A listener for all the chat creation event that happens on the connection.
+     * 
      * @author darisk
      */
     private class ChatListener implements ChatStateListener, ChatManagerListener, MessageListener {
@@ -165,20 +74,22 @@
 
 	/**
 	 * Set a notification of a new chat in android.
-	 * @param chat The chat to access by the notification
+	 * 
+	 * @param chat
+	 *            The chat to access by the notification
 	 */
 	private void notifyNewChat(IChat chat) {
 	    try {
 		String text = chat.getParticipant().getJID();
 		Notification notif = new Notification(com.beem.project.beem.R.drawable.notify_message, text, System
-		    .currentTimeMillis());
+		        .currentTimeMillis());
 		notif.defaults = Notification.DEFAULT_ALL;
 		notif.flags = Notification.FLAG_AUTO_CANCEL;
 		Intent intent = new Intent(mService, SendIM.class);
 		intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
 		intent.setData(chat.getParticipant().toUri());
 		notif.setLatestEventInfo(mService, text, mService.getString(R.string.BeemChatManagerNewMessage),
-		    PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+		        PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
 		int id = chat.hashCode();
 		mService.sendNotification(id, notif);
 	    } catch (RemoteException e) {
@@ -236,5 +147,109 @@
 	    mRemoteMessageListeners.finishBroadcast();
 	}
     }
+    /**
+     * Tag to use with log methods.
+     */
+    public static final String                       TAG                          = "BeemChatManager";
+    private final ChatManager                              mAdaptee;
+    private final Map<String, ChatAdapter>                 mChats                       = new HashMap<String, ChatAdapter>();
+    private final ChatListener                             mChatListener                = new ChatListener();
+    private final RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
+    private final RemoteCallbackList<IMessageListener>     mRemoteMessageListeners      = new RemoteCallbackList<IMessageListener>();
+
+    private final BeemService                              mService;
+
+    /**
+     * Constructor.
+     * 
+     * @param chatManager
+     *            the smack ChatManager to adapt
+     * @param service
+     *            the service which runs the chat manager
+     */
+    public BeemChatManager(final ChatManager chatManager, final BeemService service) {
+	mService = service;
+	mAdaptee = chatManager;
+	mAdaptee.addChatListener(mChatListener);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
+	mRemoteChatCreationListeners.register(listener);
+    }
+
+    /**
+     * Create a chat session.
+     * 
+     * @param contact
+     *            the contact you want to chat with
+     * @param listener
+     *            listener to use for chat events on this chat session
+     * @return the chat session
+     */
+    public IChat createChat(Contact contact, IMessageListener listener) {
+	String jid = contact.getJID();
+	return createChat(jid, listener);
+    }
+
+    /**
+     * Create a chat session.
+     * 
+     * @param jid
+     *            the jid of the contact you want to chat with
+     * @param listener
+     *            listener to use for chat events on this chat session
+     * @return the chat session
+     */
+    public IChat createChat(String jid, IMessageListener listener) {
+	mRemoteMessageListeners.register(listener);
+	String key = StringUtils.parseBareAddress(jid);
+	if (mChats.containsKey(key)) {
+	    return mChats.get(key);
+	}
+	// create the chat. the adaptee will be add automatically in the map
+	mAdaptee.createChat(key, mChatListener);
+	return mChats.get(key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void destroyChat(IChat chat) throws RemoteException {
+	// TODO gerer les resources egalement
+	Log.d(TAG, "destroy chat jid " + chat.getParticipant().getJID());
+	IChat c = mChats.remove(chat.getParticipant().getJID());
+	if (c == null)
+	    Log.w(TAG, "CA devrait pas 1!!" + chat.getParticipant().getJID());
+    }
+
+    /**
+     * Get an existing ChatAdapter or create it if necessary.
+     * 
+     * @param chat
+     *            The real instance of smack chat
+     * @return a chat adapter register in the manager
+     */
+    private ChatAdapter getChat(Chat chat) {
+	String key = StringUtils.parseBareAddress(chat.getParticipant());
+	if (mChats.containsKey(key)) {
+	    return mChats.get(key);
+	}
+	ChatAdapter res = new ChatAdapter(chat);
+	mChats.put(key, res);
+	return res;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
+	mRemoteChatCreationListeners.unregister(listener);
+    }
 
 }
--- a/src/com/beem/project/beem/service/Contact.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/Contact.java	Fri May 29 20:34:30 2009 +0200
@@ -19,6 +19,7 @@
 
 /**
  * This class contains informations on a jabber contact.
+ * 
  * @author darisk
  */
 public class Contact implements Parcelable {
@@ -28,23 +29,24 @@
      */
     public static final Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() {
 
-	@Override
-	public Contact createFromParcel(Parcel source) {
-	    return new Contact(source);
-	}
+	                                                        @Override
+	                                                        public Contact createFromParcel(Parcel source) {
+		                                                    return new Contact(source);
+	                                                        }
 
-	@Override
-	public Contact[] newArray(int size) {
-	    return new Contact[size];
-	}
-    };
+	                                                        @Override
+	                                                        public Contact[] newArray(int size) {
+		                                                    return new Contact[size];
+	                                                        }
+	                                                    };
 
-    private int mID;
-    private int mStatus;
-    private String mJID;
-    private String mMsgState;
-    private List<String> mRes;
-    private List<String> mGroups;
+    private int                                     mID;
+    private int                                     mStatus;
+    private String                                  mJID;
+    private String                                  mMsgState;
+    private List<String>                            mRes;
+    private List<String>                            mGroups;
+    private String                                  mName;
 
     /**
      * Constructor.
@@ -53,9 +55,45 @@
     }
 
     /**
+     * Construct a contact from a parcel.
+     * 
+     * @param in
+     *            parcel to use for construction
+     */
+    private Contact(final Parcel in) {
+	mID = in.readInt();
+	mStatus = in.readInt();
+	mJID = in.readString();
+	mName = in.readString();
+	mMsgState = in.readString();
+	mRes = new ArrayList<String>();
+	mGroups = new ArrayList<String>();
+	in.readStringList(mRes);
+	in.readStringList(mGroups);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param jid
+     *            JID of the contact
+     */
+    public Contact(final String jid) {
+	mJID = jid;
+	mName = jid;
+	mStatus = Status.CONTACT_STATUS_DISCONNECT;
+	mRes = new ArrayList<String>();
+	mRes.add("none");
+	mGroups = new ArrayList<String>();
+    }
+
+    /**
      * Create a contact from a Uri.
-     * @param uri an uri for the contact
-     * @throws IllegalArgumentException if it is not a xmpp uri
+     * 
+     * @param uri
+     *            an uri for the contact
+     * @throws IllegalArgumentException
+     *             if it is not a xmpp uri
      */
     public Contact(Uri uri) {
 	if (!uri.getScheme().equals("xmpp"))
@@ -64,43 +102,34 @@
     }
 
     /**
-     * Constructor.
-     * @param jid JID of the contact
+     * Add a group for the contact.
+     * 
+     * @param group
+     *            the group
      */
-    public Contact(final String jid) {
-	mJID = jid;
-	mStatus = Status.CONTACT_STATUS_DISCONNECT;
-	mRes = new ArrayList<String>();
-	mRes.add("none");
-	mGroups = new ArrayList<String>();
+    public void addGroup(String group) {
+	mGroups.add(group);
     }
 
     /**
-     * Construct a contact from a parcel.
-     * @param in parcel to use for construction
+     * Add a resource for this contact.
+     * 
+     * @param res
+     *            the resource to add
      */
-    private Contact(final Parcel in) {
-	mID = in.readInt();
-	mStatus = in.readInt();
-	mJID = in.readString();
-	mMsgState = in.readString();
-	mRes = new ArrayList<String>();
-	mGroups = new ArrayList<String>();
-	in.readStringList(mRes);
-	in.readStringList(mGroups);
+    public void addRes(String res) {
+	if (!mRes.contains(res))
+	    mRes.add(res);
     }
 
     /**
-     * {@inheritDoc}
+     * Delete a resource for this contact.
+     * 
+     * @param res
+     *            the resource de delete
      */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-	dest.writeInt(mID);
-	dest.writeInt(mStatus);
-	dest.writeString(mJID);
-	dest.writeString(mMsgState);
-	dest.writeStringList(getMRes());
-	dest.writeStringList(getGroups());
+    public void delRes(String res) {
+	mRes.remove(res);
     }
 
     /**
@@ -113,7 +142,17 @@
     }
 
     /**
+     * Get the groups the contact is in.
+     * 
+     * @return the mGroups
+     */
+    public List<String> getGroups() {
+	return mGroups;
+    }
+
+    /**
      * Get the id of the contact on the phone contact list.
+     * 
      * @return the mID
      */
     public int getID() {
@@ -121,15 +160,42 @@
     }
 
     /**
-     * set the id of te contact on the phone contact list.
-     * @param mid the mID to set
+     * Get the Jabber ID of the contact.
+     * 
+     * @return the Jabber ID
+     */
+    public String getJID() {
+	return mJID;
+    }
+
+    /**
+     * Get the list of resource for the contact.
+     * 
+     * @return the mRes
      */
-    public void setID(int mid) {
-	mID = mid;
+    public List<String> getMRes() {
+	return mRes;
+    }
+
+    /**
+     * Get the message status of the contact.
+     * 
+     * @return the message status of the contact.
+     */
+    public String getMsgState() {
+	return mMsgState;
+    }
+
+    /**
+     * @return the mName
+     */
+    public String getName() {
+	return mName;
     }
 
     /**
      * Get the status of the contact.
+     * 
      * @return the mStatus
      */
     public int getStatus() {
@@ -137,8 +203,82 @@
     }
 
     /**
+     * Set the groups the contact is in.
+     * 
+     * @param groups
+     *            list of groups
+     */
+    public void setGroups(Collection<RosterGroup> groups) {
+	this.mGroups.clear();
+	for (RosterGroup rosterGroup : groups) {
+	    mGroups.add(rosterGroup.getName());
+	}
+    }
+
+    /**
+     * Set the groups the contact is in.
+     * 
+     * @param mGroups
+     *            the mGroups to set
+     */
+    public void setGroups(List<String> mGroups) {
+	this.mGroups = mGroups;
+    }
+
+    /**
+     * set the id of te contact on the phone contact list.
+     * 
+     * @param mid
+     *            the mID to set
+     */
+    public void setID(int mid) {
+	mID = mid;
+    }
+
+    /**
+     * Set the Jabber ID of the contact.
+     * 
+     * @param jid
+     *            the jabber ID to set
+     */
+    public void setJID(String jid) {
+	mJID = jid;
+    }
+
+    /**
+     * Set a list of resource for the contact.
+     * 
+     * @param mRes
+     *            the mRes to set
+     */
+    public void setMRes(List<String> mRes) {
+	this.mRes = mRes;
+    }
+
+    /**
+     * Set the message status of the contact.
+     * 
+     * @param msgState
+     *            the message status of the contact to set
+     */
+    public void setMsgState(String msgState) {
+	mMsgState = msgState;
+    }
+
+    /**
+     * @param mName
+     *            the mName to set
+     */
+    public void setName(String mName) {
+	if (mName != null)
+	    this.mName = mName;
+    }
+
+    /**
      * Set the status of the contact.
-     * @param status the mStatus to set
+     * 
+     * @param status
+     *            the mStatus to set
      */
     public void setStatus(int status) {
 	mStatus = status;
@@ -146,7 +286,9 @@
 
     /**
      * Set the status of the contact using a presence packet.
-     * @param presence the presence containing status
+     * 
+     * @param presence
+     *            the presence containing status
      */
     public void setStatus(Presence presence) {
 	mStatus = Status.getStatusFromPresence(presence);
@@ -155,7 +297,9 @@
 
     /**
      * Set status for the contact.
-     * @param presence The presence packet which contains the status
+     * 
+     * @param presence
+     *            The presence packet which contains the status
      */
     public void setStatus(PresenceAdapter presence) {
 	mStatus = presence.getStatus();
@@ -164,71 +308,6 @@
     }
 
     /**
-     * Get the message status of the contact.
-     * @return the message status of the contact.
-     */
-    public String getMsgState() {
-	return mMsgState;
-    }
-
-    /**
-     * Set the message status of the contact.
-     * @param msgState the message status of the contact to set
-     */
-    public void setMsgState(String msgState) {
-	mMsgState = msgState;
-    }
-
-    /**
-     * Get the Jabber ID of the contact.
-     * @return the Jabber ID
-     */
-    public String getJID() {
-	return mJID;
-    }
-
-    /**
-     * Set the Jabber ID of the contact.
-     * @param jid the jabber ID to set
-     */
-    public void setJID(String jid) {
-	mJID = jid;
-    }
-
-    /**
-     * Add a resource for this contact.
-     * @param res the resource to add
-     */
-    public void addRes(String res) {
-	if (!mRes.contains(res))
-	    mRes.add(res);
-    }
-
-    /**
-     * Delete a resource for this contact.
-     * @param res the resource de delete
-     */
-    public void delRes(String res) {
-	mRes.remove(res);
-    }
-
-    /**
-     * Set a list of resource for the contact.
-     * @param mRes the mRes to set
-     */
-    public void setMRes(List<String> mRes) {
-	this.mRes = mRes;
-    }
-
-    /**
-     * Get the list of resource for the contact.
-     * @return the mRes
-     */
-    public List<String> getMRes() {
-	return mRes;
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
@@ -239,42 +318,8 @@
     }
 
     /**
-     * Set the groups the contact is in.
-     * @param groups list of groups
-     */
-    public void setGroups(Collection<RosterGroup> groups) {
-	this.mGroups.clear();
-	for (RosterGroup rosterGroup : groups) {
-	    mGroups.add(rosterGroup.getName());
-	}
-    }
-
-    /**
-     * Add a group for the contact.
-     * @param group the group
-     */
-    public void addGroup(String group) {
-	mGroups.add(group);
-    }
-
-    /**
-     * Set the groups the contact is in.
-     * @param mGroups the mGroups to set
-     */
-    public void setGroups(List<String> mGroups) {
-	this.mGroups = mGroups;
-    }
-
-    /**
-     * Get the groups the contact is in.
-     * @return the mGroups
-     */
-    public List<String> getGroups() {
-	return mGroups;
-    }
-
-    /**
      * Get a URI to access the contact.
+     * 
      * @return the URI
      */
     public Uri toUri() {
@@ -284,4 +329,18 @@
 	return u;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+	dest.writeInt(mID);
+	dest.writeInt(mStatus);
+	dest.writeString(mJID);
+	dest.writeString(mName);
+	dest.writeString(mMsgState);
+	dest.writeStringList(getMRes());
+	dest.writeStringList(getGroups());
+    }
+
 }
--- a/src/com/beem/project/beem/service/PresenceAdapter.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/PresenceAdapter.java	Fri May 29 20:34:30 2009 +0200
@@ -2,144 +2,140 @@
 
 import org.jivesoftware.smack.packet.Presence;
 
-import com.beem.project.beem.utils.PresenceType;
-import com.beem.project.beem.utils.Status;
-
 import android.os.Parcel;
 import android.os.Parcelable;
 
-public class PresenceAdapter implements  Parcelable {
-	
-	private int mType;
-	private int mStatus;
-	private String mTo;
-	private String mFrom;
-	private String mStatusText;
-	
-	/**
-	 * Parcelable.Creator needs by Android.
-	 */
-	public static final Parcelable.Creator<PresenceAdapter> CREATOR = new Parcelable.Creator<PresenceAdapter>() {
+import com.beem.project.beem.utils.PresenceType;
+import com.beem.project.beem.utils.Status;
+
+public class PresenceAdapter implements Parcelable {
+
+    private int                                             mType;
+    private int                                             mStatus;
+    private String                                          mTo;
+    private String                                          mFrom;
+    private String                                          mStatusText;
 
-		@Override
-		public PresenceAdapter createFromParcel(Parcel source) {
-			return new PresenceAdapter(source);
-		}
+    /**
+     * Parcelable.Creator needs by Android.
+     */
+    public static final Parcelable.Creator<PresenceAdapter> CREATOR = new Parcelable.Creator<PresenceAdapter>() {
+
+	                                                                @Override
+	                                                                public PresenceAdapter createFromParcel(
+	                                                                        Parcel source) {
+		                                                            return new PresenceAdapter(source);
+	                                                                }
+
+	                                                                @Override
+	                                                                public PresenceAdapter[] newArray(int size) {
+		                                                            return new PresenceAdapter[size];
+	                                                                }
+	                                                            };
 
-		@Override
-		public PresenceAdapter[] newArray(int size) {
-			return new PresenceAdapter[size];
-		}
-	};
-	
-	public PresenceAdapter(Presence presence) {
-		mType = PresenceType.getPresenceType(presence);
-		mStatus = Status.getStatusFromPresence(presence);
-		mTo = presence.getTo();
-		mFrom = presence.getFrom();
-		mStatusText = presence.getStatus();
-	}
-	
-	
-	public PresenceAdapter(Parcel source) {
-		mType = source.readInt();
-		mStatus = source.readInt();
-		mTo = source.readString();
-		mFrom = source.readString();
-		mStatusText = source.readString();
-	}
+    public PresenceAdapter(Parcel source) {
+	mType = source.readInt();
+	mStatus = source.readInt();
+	mTo = source.readString();
+	mFrom = source.readString();
+	mStatusText = source.readString();
+    }
+
+    public PresenceAdapter(Presence presence) {
+	mType = PresenceType.getPresenceType(presence);
+	mStatus = Status.getStatusFromPresence(presence);
+	mTo = presence.getTo();
+	mFrom = presence.getFrom();
+	mStatusText = presence.getStatus();
+    }
 
-	@Override
-	public int describeContents() {
-		// TODO Auto-generated method stub
-		return 0;
-	}
+    @Override
+    public int describeContents() {
+	// TODO Auto-generated method stub
+	return 0;
+    }
 
-	@Override
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeInt(mType);
-		dest.writeInt(mStatus);
-		dest.writeString(mTo);
-		dest.writeString(mFrom);
-		dest.writeString(mStatusText);
-	}
+    /**
+     * @return the mFrom
+     */
+    public String getFrom() {
+	return mFrom;
+    }
 
-
-	/**
-	 * @param mStatus the mStatus to set
-	 */
-	public void setStatus(int mStatus) {
-	    this.mStatus = mStatus;
-	}
-
+    /**
+     * @return the mStatus
+     */
+    public int getStatus() {
+	return mStatus;
+    }
 
-	/**
-	 * @return the mStatus
-	 */
-	public int getStatus() {
-	    return mStatus;
-	}
+    /**
+     * @return the mStatusText
+     */
+    public String getStatusText() {
+	return mStatusText;
+    }
 
-
-	/**
-	 * @param mType the mType to set
-	 */
-	public void setType(int mType) {
-	    this.mType = mType;
-	}
+    /**
+     * @return the mTo
+     */
+    public String getTo() {
+	return mTo;
+    }
 
-
-	/**
-	 * @return the mType
-	 */
-	public int getType() {
-	    return mType;
-	}
+    /**
+     * @return the mType
+     */
+    public int getType() {
+	return mType;
+    }
 
-
-	/**
-	 * @param mTo the mTo to set
-	 */
-	public void setTo(String mTo) {
-	    this.mTo = mTo;
-	}
+    /**
+     * @param mFrom
+     *            the mFrom to set
+     */
+    public void setFrom(String mFrom) {
+	this.mFrom = mFrom;
+    }
 
-	/**
-	 * @return the mTo
-	 */
-	public String getTo() {
-	    return mTo;
-	}
-
+    /**
+     * @param mStatus
+     *            the mStatus to set
+     */
+    public void setStatus(int mStatus) {
+	this.mStatus = mStatus;
+    }
 
-	/**
-	 * @param mFrom the mFrom to set
-	 */
-	public void setFrom(String mFrom) {
-	    this.mFrom = mFrom;
-	}
-
+    /**
+     * @param mStatusText
+     *            the mStatusText to set
+     */
+    public void setStatusText(String mStatusText) {
+	this.mStatusText = mStatusText;
+    }
 
-	/**
-	 * @return the mFrom
-	 */
-	public String getFrom() {
-	    return mFrom;
-	}
-
+    /**
+     * @param mTo
+     *            the mTo to set
+     */
+    public void setTo(String mTo) {
+	this.mTo = mTo;
+    }
 
-	/**
-	 * @param mStatusText the mStatusText to set
-	 */
-	public void setStatusText(String mStatusText) {
-	    this.mStatusText = mStatusText;
-	}
-
+    /**
+     * @param mType
+     *            the mType to set
+     */
+    public void setType(int mType) {
+	this.mType = mType;
+    }
 
-	/**
-	 * @return the mStatusText
-	 */
-	public String getStatusText() {
-	    return mStatusText;
-	}
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+	dest.writeInt(mType);
+	dest.writeInt(mStatus);
+	dest.writeString(mTo);
+	dest.writeString(mFrom);
+	dest.writeString(mStatusText);
+    }
 }
--- a/src/com/beem/project/beem/service/RosterAdapter.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/RosterAdapter.java	Fri May 29 20:34:30 2009 +0200
@@ -17,117 +17,22 @@
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.util.StringUtils;
 
-import com.beem.project.beem.service.aidl.IBeemRosterListener;
-
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.beem.project.beem.service.aidl.IBeemRosterListener;
+
 /**
  * This class implement a Roster adapter for BEEM.
+ * 
  * @author darisk
  */
 public class RosterAdapter extends com.beem.project.beem.service.aidl.IRoster.Stub {
 
-    private static final String TAG = "RosterAdapter";
-    private Roster mAdaptee;
-    private RemoteCallbackList<IBeemRosterListener> mRemoteRosListeners = new RemoteCallbackList<IBeemRosterListener>();
-    private Map<String, Contact> mContacts = new HashMap<String, Contact>();
-
-    private RosterListenerAdapter mRosterListener = new RosterListenerAdapter();
-
-    /**
-     * Constructor.
-     * @param roster the roster to adapt
-     */
-    public RosterAdapter(final Roster roster) {
-	mAdaptee = roster;
-	roster.addRosterListener(mRosterListener);
-	for (RosterEntry entry : roster.getEntries()) {
-	    String user = StringUtils.parseBareAddress(entry.getUser());
-	    if (!mContacts.containsKey(user)) {
-		Contact c = new Contact(user);
-		c.setStatus(roster.getPresence(user));
-		c.setGroups(entry.getGroups());
-		mContacts.put(user, c);
-	    }
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void createGroup(String groupname) throws RemoteException {
-	mAdaptee.createGroup(groupname);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Contact addContact(String user, String name, String[] groups) throws RemoteException {
-	try {
-	    mAdaptee.createEntry(user, name, groups);
-	    Contact res = new Contact(user);
-	    mContacts.put(user, res);
-	    for (String group : groups) {
-		//mAdaptee.createGroup(group);
-		res.addGroup(group);
-	    }
-	    return res;
-	} catch (XMPPException e) {
-	    Log.e(TAG, "Error while adding new contact", e);
-	    return null;
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void deleteContact(Contact contact) throws RemoteException {
-	mContacts.remove(contact.getJID());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void addConnectionListener(IBeemRosterListener listen) throws RemoteException {
-	if (listen != null)
-	    mRemoteRosListeners.register(listen);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void removeConnectionListener(IBeemRosterListener listen) throws RemoteException {
-	if (listen != null)
-	    mRemoteRosListeners.unregister(listen);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Contact getContact(String jid) throws RemoteException {
-	return mContacts.get(jid);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<Contact> getContactList() throws RemoteException {
-	List<Contact> res = new ArrayList<Contact>();
-	res.addAll(mContacts.values());
-	return res;
-    }
-
     /**
      * Listener for the roster events. It will call the remote listeners registered.
+     * 
      * @author darisk
      */
     private class RosterListenerAdapter implements RosterListener {
@@ -225,6 +130,7 @@
 	    c.addRes(StringUtils.parseResource(presence.getFrom()));
 	    c.setStatus(mAdaptee.getPresence(presence.getFrom()));
 	    c.setMsgState(presence.getStatus());
+	    c.setName(mAdaptee.getEntry(user).getName());
 	    /* redispatch vers les IBeemRosterListener */
 	    final int n = mRemoteRosListeners.beginBroadcast();
 
@@ -242,6 +148,98 @@
 	}
     }
 
+    private static final String                     TAG                 = "RosterAdapter";
+    private Roster                                  mAdaptee;
+    private RemoteCallbackList<IBeemRosterListener> mRemoteRosListeners = new RemoteCallbackList<IBeemRosterListener>();
+
+    private Map<String, Contact>                    mContacts           = new HashMap<String, Contact>();
+
+    private RosterListenerAdapter                   mRosterListener     = new RosterListenerAdapter();
+
+    /**
+     * Constructor.
+     * 
+     * @param roster
+     *            the roster to adapt
+     */
+    public RosterAdapter(final Roster roster) {
+	mAdaptee = roster;
+	roster.addRosterListener(mRosterListener);
+	for (RosterEntry entry : roster.getEntries()) {
+	    String user = StringUtils.parseBareAddress(entry.getUser());
+	    if (!mContacts.containsKey(user)) {
+		Contact c = new Contact(user);
+		c.setStatus(roster.getPresence(user));
+		c.setGroups(entry.getGroups());
+		c.setName(entry.getName());
+		mContacts.put(user, c);
+	    }
+	}
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addConnectionListener(IBeemRosterListener listen) throws RemoteException {
+	if (listen != null)
+	    mRemoteRosListeners.register(listen);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Contact addContact(String user, String name, String[] groups) throws RemoteException {
+	try {
+	    mAdaptee.createEntry(user, name, groups);
+	    Contact res = new Contact(user);
+	    mContacts.put(user, res);
+	    for (String group : groups) {
+		// mAdaptee.createGroup(group);
+		res.addGroup(group);
+	    }
+	    return res;
+	} catch (XMPPException e) {
+	    Log.e(TAG, "Error while adding new contact", e);
+	    return null;
+	}
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void createGroup(String groupname) throws RemoteException {
+	mAdaptee.createGroup(groupname);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void deleteContact(Contact contact) throws RemoteException {
+	mContacts.remove(contact.getJID());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Contact getContact(String jid) throws RemoteException {
+	return mContacts.get(jid);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<Contact> getContactList() throws RemoteException {
+	List<Contact> res = new ArrayList<Contact>();
+	res.addAll(mContacts.values());
+	return res;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -255,4 +253,22 @@
 	return result;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeConnectionListener(IBeemRosterListener listen) throws RemoteException {
+	if (listen != null)
+	    mRemoteRosListeners.unregister(listen);
+    }
+
+    /**
+     * 
+     */
+    @Override
+    public void setContactName(String jid, String name) throws RemoteException {
+	mContacts.get(jid).setName(name);
+	mAdaptee.getEntry(jid).setName(name);
+    }
+
 }
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Fri May 29 20:34:30 2009 +0200
@@ -11,9 +11,11 @@
 import org.jivesoftware.smackx.ChatStateManager;
 import org.jivesoftware.smackx.ServiceDiscoveryManager;
 import org.jivesoftware.smackx.jingle.JingleManager;
+
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
+
 import com.beem.project.beem.BeemService;
 import com.beem.project.beem.service.aidl.IBeemConnectionListener;
 import com.beem.project.beem.service.aidl.IChatManager;
@@ -22,170 +24,14 @@
 
 /**
  * This class implements an adapter for XMPPConnection.
+ * 
  * @author darisk
  */
 public class XmppConnectionAdapter extends IXmppConnection.Stub {
 
-    private static final String TAG = "XMPPConnectionAdapter";
-    private XMPPConnection mAdaptee;
-    private IChatManager mChatManager;
-    private String mLogin;
-    private String mPassword;
-    private RosterAdapter mRoster;
-    private BeemService mService;
-
-    private RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
-    private ConnexionListenerAdapter mConListener = new ConnexionListenerAdapter();
-
-    /**
-     * Constructor.
-     * @param con The connection to adapt
-     * @param login The login to use
-     * @param password The password to use
-     */
-    public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password, BeemService service) {
-	mAdaptee = con;
-	mLogin = login;
-	mPassword = password;
-	mService = service;
-    }
-
-    /**
-     * Constructor.
-     * @param serviceName name of the service to connect to
-     * @param login login to use on connect
-     * @param password password to use on connect
-     */
-    public XmppConnectionAdapter(final String serviceName, final String login, final String password, BeemService service) {
-	this(new XMPPConnection(serviceName), login, password, service);
-    }
-
-    /**
-     * Constructor.
-     * @param config Configuration to use in order to connect
-     * @param login login to use on connect
-     * @param password password to use on connect
-     */
-    public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password, BeemService service) {
-	this(new XMPPConnection(config), login, password, service);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean connectSync() throws RemoteException {
-	try {
-	    mAdaptee.connect();
-	    mAdaptee.addConnectionListener(mConListener);
-	    mAdaptee.login(mLogin, mPassword, "BEEM");
-	    
-	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
-	    // TODO find why this cause a null pointer exception
-	    this.initFeatures(); // pour declarer les features xmpp qu'on supporte
-	    ChatStateManager.getInstance(mAdaptee);
-	    triggerAsynchronousConnectEvent();
-	    return true;
-	} catch (XMPPException e) {
-	    Log.e(TAG, "Error while connecting", e);
-	    if (e.getXMPPError() != null)
-		mConListener.connectionFailed(e.getXMPPError().getMessage()); //
-	    else
-		mConListener.connectionFailed("Error On Connection");
-	}
-	return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean disconnect() {
-	mAdaptee.disconnect();
-	return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public IRoster getRoster() throws RemoteException {
-	if (mRoster != null)
-	    return mRoster;
-	Roster adap = mAdaptee.getRoster();
-	if (adap == null)
-	    return null;
-	mRoster = new RosterAdapter(adap);
-	return mRoster;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final void connectAsync() throws RemoteException {
-	Thread t = new Thread(new Runnable() {
-
-	    @Override
-	    public void run() {
-		try {
-		    connectSync();
-		} catch (RemoteException e) {
-		    Log.e(TAG, "Error while connecting", e);
-		}
-	    }
-	});
-	t.start();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void addConnectionListener(IBeemConnectionListener listen) throws RemoteException {
-	if (listen != null)
-	    mRemoteConnListeners.register(listen);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void removeConnectionListener(IBeemConnectionListener listen) throws RemoteException {
-	if (listen != null)
-	    mRemoteConnListeners.unregister(listen);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public IChatManager getChatManager() throws RemoteException {
-	return mChatManager;
-    }
-
-    /**
-     * Trigger Connection event.
-     */
-    private void triggerAsynchronousConnectEvent() {
-	mConListener.onConnect();
-    }
-
-    /**
-     * enregistre les features dispo dans notre version Liste de features que Telepathy supporte.
-     */
-    private void initFeatures() {
-	ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
-	if (sdm == null)
-	    sdm = new ServiceDiscoveryManager(mAdaptee);
-	sdm.addFeature("http://jabber.org/protocol/disco#info");
-	JingleManager.setJingleServiceEnabled();
-	// sdm.addFeature("http://jabber.org/protocol/nick");
-
-    }
-
     /**
      * Listener for XMPP connection events. It will calls the remote listeners for connexion events.
+     * 
      * @author darisk
      */
     private class ConnexionListenerAdapter implements ConnectionListener {
@@ -198,25 +44,6 @@
 	}
 
 	/**
-	 * Method to execute when a connection event occurs.
-	 */
-	public void onConnect() {
-	    final int n = mRemoteConnListeners.beginBroadcast();
-
-	    for (int i = 0; i < n; i++) {
-		IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
-		try {
-		    listener.onConnect();
-		} catch (RemoteException e) {
-		    // The RemoteCallbackList will take care of removing the
-		    // dead listeners.
-		    Log.w(TAG, "Error while triggering remote connection listeners", e);
-		}
-	    }
-	    mRemoteConnListeners.finishBroadcast();
-	}
-
-	/**
 	 * {@inheritDoc}
 	 */
 	@Override
@@ -258,6 +85,42 @@
 	    mRemoteConnListeners.finishBroadcast();
 	}
 
+	public void connectionFailed(String errorMsg) {
+	    Log.i(TAG, "Connection Failed");
+	    final int n = mRemoteConnListeners.beginBroadcast();
+
+	    for (int i = 0; i < n; i++) {
+		IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
+		try {
+		    listener.connectionFailed(errorMsg);
+		} catch (RemoteException e) {
+		    // The RemoteCallbackList will take care of removing the
+		    // dead listeners.
+		    Log.w(TAG, "Error while triggering remote connection listeners", e);
+		}
+	    }
+	    mRemoteConnListeners.finishBroadcast();
+	}
+
+	/**
+	 * Method to execute when a connection event occurs.
+	 */
+	public void onConnect() {
+	    final int n = mRemoteConnListeners.beginBroadcast();
+
+	    for (int i = 0; i < n; i++) {
+		IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
+		try {
+		    listener.onConnect();
+		} catch (RemoteException e) {
+		    // The RemoteCallbackList will take care of removing the
+		    // dead listeners.
+		    Log.w(TAG, "Error while triggering remote connection listeners", e);
+		}
+	    }
+	    mRemoteConnListeners.finishBroadcast();
+	}
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -317,39 +180,197 @@
 	    }
 	    mRemoteConnListeners.finishBroadcast();
 	}
-	
-	public void connectionFailed(String errorMsg) {
-	    Log.i(TAG, "Connection Failed");
-	    final int n = mRemoteConnListeners.beginBroadcast();
+    }
+
+    private static final String                         TAG                  = "XMPPConnectionAdapter";
+    private XMPPConnection                              mAdaptee;
+    private IChatManager                                mChatManager;
+    private String                                      mLogin;
+    private String                                      mPassword;
+    private RosterAdapter                               mRoster;
+
+    private BeemService                                 mService;
+    private RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
+
+    private ConnexionListenerAdapter                    mConListener         = new ConnexionListenerAdapter();
+
+    /**
+     * Constructor.
+     * 
+     * @param config
+     *            Configuration to use in order to connect
+     * @param login
+     *            login to use on connect
+     * @param password
+     *            password to use on connect
+     */
+    public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password,
+	    BeemService service) {
+	this(new XMPPConnection(config), login, password, service);
+    }
 
-	    for (int i = 0; i < n; i++) {
-		IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i);
+    /**
+     * Constructor.
+     * 
+     * @param serviceName
+     *            name of the service to connect to
+     * @param login
+     *            login to use on connect
+     * @param password
+     *            password to use on connect
+     */
+    public XmppConnectionAdapter(final String serviceName, final String login, final String password,
+	    BeemService service) {
+	this(new XMPPConnection(serviceName), login, password, service);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param con
+     *            The connection to adapt
+     * @param login
+     *            The login to use
+     * @param password
+     *            The password to use
+     */
+    public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password,
+	    BeemService service) {
+	mAdaptee = con;
+	mLogin = login;
+	mPassword = password;
+	mService = service;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addConnectionListener(IBeemConnectionListener listen) throws RemoteException {
+	if (listen != null)
+	    mRemoteConnListeners.register(listen);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final void connectAsync() throws RemoteException {
+	Thread t = new Thread(new Runnable() {
+
+	    @Override
+	    public void run() {
 		try {
-		    listener.connectionFailed(errorMsg);
+		    connectSync();
 		} catch (RemoteException e) {
-		    // The RemoteCallbackList will take care of removing the
-		    // dead listeners.
-		    Log.w(TAG, "Error while triggering remote connection listeners", e);
+		    Log.e(TAG, "Error while connecting", e);
 		}
 	    }
-	    mRemoteConnListeners.finishBroadcast();
+	});
+	t.start();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean connectSync() throws RemoteException {
+	try {
+	    mAdaptee.connect();
+	    mAdaptee.addConnectionListener(mConListener);
+	    mAdaptee.login(mLogin, mPassword, "BEEM");
+
+	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
+	    // TODO find why this cause a null pointer exception
+	    this.initFeatures(); // pour declarer les features xmpp qu'on supporte
+	    ChatStateManager.getInstance(mAdaptee);
+	    triggerAsynchronousConnectEvent();
+	    return true;
+	} catch (XMPPException e) {
+	    Log.e(TAG, "Error while connecting", e);
+	    if (e.getXMPPError() != null)
+		mConListener.connectionFailed(e.getXMPPError().getMessage()); //
+	    else
+		mConListener.connectionFailed("Error On Connection");
 	}
+	return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean disconnect() {
+	mAdaptee.disconnect();
+	return true;
+    }
+
+    public XMPPConnection getAdaptee() {
+	return mAdaptee;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IChatManager getChatManager() throws RemoteException {
+	return mChatManager;
+    }
+
+    public BeemService getContext() {
+	return mService;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IRoster getRoster() throws RemoteException {
+	if (mRoster != null)
+	    return mRoster;
+	Roster adap = mAdaptee.getRoster();
+	if (adap == null)
+	    return null;
+	mRoster = new RosterAdapter(adap);
+	return mRoster;
+    }
+
+    /**
+     * enregistre les features dispo dans notre version Liste de features que Telepathy supporte.
+     */
+    private void initFeatures() {
+	ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
+	if (sdm == null)
+	    sdm = new ServiceDiscoveryManager(mAdaptee);
+	sdm.addFeature("http://jabber.org/protocol/disco#info");
+	JingleManager.setJingleServiceEnabled();
+	// sdm.addFeature("http://jabber.org/protocol/nick");
+
     }
 
     /**
      * Returns true if currently authenticated by successfully calling the login method.
+     * 
      * @return true when successfully authenticated
      */
     public boolean isAuthentificated() {
 	return mAdaptee.isAuthenticated();
     }
 
-    public XMPPConnection getAdaptee() {
-	return mAdaptee;
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeConnectionListener(IBeemConnectionListener listen) throws RemoteException {
+	if (listen != null)
+	    mRemoteConnListeners.unregister(listen);
     }
-    
-    public BeemService getContext() {
-	return mService;
+
+    /**
+     * Trigger Connection event.
+     */
+    private void triggerAsynchronousConnectEvent() {
+	mConListener.onConnect();
     }
-    
+
 }
--- a/src/com/beem/project/beem/service/XmppFacade.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/XmppFacade.java	Fri May 29 20:34:30 2009 +0200
@@ -17,17 +17,21 @@
 
 /**
  * This class is a facade for the Beem Service.
+ * 
  * @author darisk
  */
 public class XmppFacade extends IXmppFacade.Stub {
 
     private XmppConnectionAdapter mConnexion;
-    private BeemService mBeemService;
+    private BeemService           mBeemService;
 
     /**
      * Constructor for XMPPFacade.
-     * @param connection the connection use by the facade
-     * @param service the service which holds the facade
+     * 
+     * @param connection
+     *            the connection use by the facade
+     * @param service
+     *            the service which holds the facade
      */
     public XmppFacade(final XmppConnectionAdapter connection, final BeemService service) {
 	this.mConnexion = connection;
@@ -38,6 +42,32 @@
      * {@inheritDoc}
      */
     @Override
+    public void changeStatus(int status, String msg) {
+	Presence pres = new Presence(Presence.Type.available);
+	if (msg != null)
+	    pres.setStatus(msg);
+	Presence.Mode mode = com.beem.project.beem.utils.Status.getPresenceModeFromStatus(status);
+	if (mode != null)
+	    pres.setMode(mode);
+	mConnexion.getAdaptee().sendPacket(pres);
+
+	Notification mStatusNotification;
+	String text = (msg == null ? "" : msg);
+	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.notify_signal, text, System
+	        .currentTimeMillis());
+	mStatusNotification.defaults = Notification.DEFAULT_ALL;
+	mStatusNotification.flags = Notification.FLAG_NO_CLEAR;
+
+	// mStatusNotification.contentView = ;
+	mStatusNotification.setLatestEventInfo(mBeemService, "Beem Status", text, PendingIntent.getActivity(
+	        mBeemService, 0, new Intent(mBeemService, ChangeStatus.class), 0));
+	mBeemService.sendNotification(BeemService.NOTIFICATION_STATUS_ID, mStatusNotification);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void connectAsync() throws RemoteException {
 	mConnexion.connectAsync();
     }
@@ -70,14 +100,6 @@
      * {@inheritDoc}
      */
     @Override
-    public IRoster getRoster() throws RemoteException {
-	return mConnexion.getRoster();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
     public IChatManager getChatManager() throws RemoteException {
 	return mConnexion.getChatManager();
     }
@@ -86,25 +108,8 @@
      * {@inheritDoc}
      */
     @Override
-    public void changeStatus(int status, String msg) {
-	Presence pres = new Presence(Presence.Type.available);
-	if (msg != null)
-	    pres.setStatus(msg);
-	Presence.Mode mode = com.beem.project.beem.utils.Status.getPresenceModeFromStatus(status);
-	if (mode != null)
-	    pres.setMode(mode);
-	mConnexion.getAdaptee().sendPacket(pres);
-	
-	Notification mStatusNotification;
-	String text = (msg == null ? "" : msg);
-	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.notify_signal, text, System.currentTimeMillis());
-	mStatusNotification.defaults = Notification.DEFAULT_ALL;
-	mStatusNotification.flags = Notification.FLAG_NO_CLEAR;
-
-	// mStatusNotification.contentView = ;
-	mStatusNotification.setLatestEventInfo(mBeemService, "Beem Status", text, PendingIntent.getActivity(
-	    mBeemService, 0, new Intent(mBeemService,ChangeStatus.class), 0));
-	mBeemService.sendNotification(BeemService.NOTIFICATION_STATUS_ID, mStatusNotification);
+    public IRoster getRoster() throws RemoteException {
+	return mConnexion.getRoster();
     }
 
     @Override
--- a/src/com/beem/project/beem/service/aidl/IRoster.aidl	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/service/aidl/IRoster.aidl	Fri May 29 20:34:30 2009 +0200
@@ -10,6 +10,7 @@
     void deleteContact(in Contact contact);
     
     Contact getContact(in String jid);
+    void setContactName(in String jid, in String name);
      
     void createGroup(in String groupname);
     
--- a/src/com/beem/project/beem/ui/AccountCreation.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/AccountCreation.java	Fri May 29 20:34:30 2009 +0200
@@ -11,8 +11,6 @@
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 
-import com.beem.project.beem.R;
-
 import android.app.Activity;
 import android.content.SharedPreferences;
 import android.os.Bundle;
@@ -23,70 +21,66 @@
 import android.widget.EditText;
 import android.widget.Toast;
 
+import com.beem.project.beem.R;
+
 /**
  * @author nikita
- *
  */
-public class AccountCreation extends Activity {    
+public class AccountCreation extends Activity {
 
-    protected static final String TAG = "AccountCreation";
-    private SharedPreferences mSettings;
-    Map<String, String> mAttributes = new HashMap<String, String>();
+    protected static final String TAG         = "AccountCreation";
+    private SharedPreferences     mSettings;
+    Map<String, String>           mAttributes = new HashMap<String, String>();
+
+    private OnClickListener       mOkListener = new OnClickListener() {
 
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-	super.onCreate(savedInstanceState);
-	setContentView(R.layout.accountcreation);
-	Button ok = (Button) findViewById(R.id.ac_ok);
-	mSettings = getSharedPreferences(
-		getString(R.string.PreferenceFileName), MODE_PRIVATE);
-	ok.setOnClickListener(mOkListener);
-    }
+	                                          @Override
+	                                          public void onClick(View v) {
+		                                      boolean valid = true;
+		                                      if (getWidgetText(R.id.ac_login).length() == 0) {
+		                                          valid = false;
+		                                      } else {
+		                                          mAttributes.put("login", getWidgetText(R.id.ac_login));
+		                                          mAttributes.put("name", getWidgetText(R.id.ac_login));
+		                                      }
+		                                      if (getWidgetText(R.id.ac_password).length() == 0
+		                                              || !getWidgetText(R.id.ac_password).contains(
+		                                                      getWidgetText(R.id.ac_password2))) {
+		                                          valid = false;
 
-    private OnClickListener mOkListener = new OnClickListener() {
-	
-	@Override
-	public void onClick(View v) {
-	    boolean valid = true;
-	    if (getWidgetText(R.id.ac_login).length() == 0) {
-		valid = false;
-	    } else {
-		mAttributes.put("login", getWidgetText(R.id.ac_login));
-		mAttributes.put("name", getWidgetText(R.id.ac_login));
-	    }
-	    if (getWidgetText(R.id.ac_password).length() == 0 || !getWidgetText(R.id.ac_password).contains(getWidgetText(R.id.ac_password2))) {
-		valid = false;
-		
-	    } else {
-		mAttributes.put("password", getWidgetText(R.id.ac_password));
-	    }
-	    if (getWidgetText(R.id.ac_email).length() == 0) {
-		valid = false;
-	    } else {
-		mAttributes.put("email", getWidgetText(R.id.ac_email));
-	    }
-	    
-	    if (valid) {
-		setResult(RESULT_OK);
-		try {
-		    createAccount();
-		    Toast.makeText(AccountCreation.this, getString(R.string.ACCreated),
-	                    Toast.LENGTH_SHORT).show();
-		    finish();
-		} catch (XMPPException e) {
-		    Log.e(TAG, "Account creation failed", e);
-		    Toast.makeText(AccountCreation.this, e.getMessage(),
-	                    Toast.LENGTH_SHORT).show();
-		    e.printStackTrace();
-		}
-	    } else {
-		Toast.makeText(AccountCreation.this, getString(R.string.ACBadForm),
-                    Toast.LENGTH_SHORT).show();
-		setResult(RESULT_CANCELED);
-	    }
-	    
-	}
-    };
+		                                      } else {
+		                                          mAttributes.put("password", getWidgetText(R.id.ac_password));
+		                                      }
+		                                      if (getWidgetText(R.id.ac_email).length() == 0) {
+		                                          valid = false;
+		                                      } else {
+		                                          mAttributes.put("email", getWidgetText(R.id.ac_email));
+		                                      }
+
+		                                      if (valid) {
+		                                          setResult(RESULT_OK);
+		                                          try {
+			                                      createAccount();
+			                                      Toast
+			                                              .makeText(AccountCreation.this,
+			                                                      getString(R.string.ACCreated),
+			                                                      Toast.LENGTH_SHORT).show();
+			                                      finish();
+		                                          } catch (XMPPException e) {
+			                                      Log.e(TAG, "Account creation failed", e);
+			                                      Toast.makeText(AccountCreation.this, e.getMessage(),
+			                                              Toast.LENGTH_SHORT).show();
+			                                      e.printStackTrace();
+		                                          }
+		                                      } else {
+		                                          Toast.makeText(AccountCreation.this,
+		                                                  getString(R.string.ACBadForm), Toast.LENGTH_SHORT)
+		                                                  .show();
+		                                          setResult(RESULT_CANCELED);
+		                                      }
+
+	                                          }
+	                                      };
 
     protected void createAccount() throws XMPPException {
 	String mHost = mSettings.getString(getString(R.string.PreferenceHostKey), "");
@@ -96,14 +90,23 @@
 	accM.createAccount(mAttributes.get("login"), mAttributes.get("password"), mAttributes);
 	xmmpCo.disconnect();
 	SharedPreferences.Editor editor = mSettings.edit();
-	
+
 	editor.putString(getString(R.string.PreferenceLoginKey), mAttributes.get("login"));
 	editor.putString(getString(R.string.PreferencePasswordKey), mAttributes.get("password"));
-	editor.commit();	
+	editor.commit();
     }
-    
+
     private String getWidgetText(int id) {
 	EditText widget = (EditText) this.findViewById(id);
 	return widget.getText().toString();
     }
-}
\ No newline at end of file
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.accountcreation);
+	Button ok = (Button) findViewById(R.id.ac_ok);
+	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	ok.setOnClickListener(mOkListener);
+    }
+}
--- a/src/com/beem/project/beem/ui/AddContact.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/AddContact.java	Fri May 29 20:34:30 2009 +0200
@@ -6,10 +6,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import com.beem.project.beem.BeemApplication;
-import com.beem.project.beem.R;
-import com.beem.project.beem.service.aidl.IXmppFacade;
-
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -19,71 +15,76 @@
 import android.widget.EditText;
 import android.widget.Toast;
 
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.aidl.IXmppFacade;
+
 /**
  * @author nikita
- *
  */
 public class AddContact extends Activity {
-    
-    protected static final String TAG = "AddContact";
-    private String mLogin;
-    private String mAlias;
-    private List<String> mGroup = new ArrayList<String>();
-    private IXmppFacade mService;
+
+    protected static final String TAG         = "AddContact";
+    private String                mLogin;
+    private String                mAlias;
+    private final List<String>          mGroup      = new ArrayList<String>();
+    private IXmppFacade           mService;
+
+    private final OnClickListener       mOkListener = new OnClickListener() {
+
+	                                          @Override
+	                                          public void onClick(View v) {
+		                                      boolean valid = true;
+		                                      if (getWidgetText(R.id.addc_login).length() == 0) {
+		                                          valid = false;
+		                                      } else {
+		                                          mLogin = getWidgetText(R.id.addc_login);
+		                                      }
+		                                      if (getWidgetText(R.id.addc_alias).length() == 0) {
+		                                          valid = false;
+		                                      } else {
+		                                          mAlias = getWidgetText(R.id.addc_alias);
+		                                      }
+		                                      if (getWidgetText(R.id.addc_group).length() == 0) {
+		                                          valid = false;
+		                                      } else {
+		                                          mGroup.add(getWidgetText(R.id.addc_group));
+		                                      }
+		                                      if (valid) {
+		                                          try {
+			                                      mService.getRoster().addContact(mLogin, mAlias,
+			                                              mGroup.toArray(new String[mGroup.size()]));
+			                                      Toast.makeText(AddContact.this,
+			                                              getString(R.string.AddCContactAdded),
+			                                              Toast.LENGTH_SHORT).show();
+			                                      finish();
+		                                          } catch (RemoteException e) {
+			                                      Toast.makeText(AddContact.this, e.getMessage(),
+			                                              Toast.LENGTH_SHORT).show();
+			                                      e.printStackTrace();
+		                                          }
+		                                          setResult(RESULT_OK);
+		                                      } else {
+		                                          Toast.makeText(AddContact.this,
+		                                                  getString(R.string.AddCBadForm), Toast.LENGTH_SHORT)
+		                                                  .show();
+		                                          setResult(RESULT_CANCELED);
+		                                      }
+
+	                                          }
+	                                      };
+
+    private String getWidgetText(int id) {
+	EditText widget = (EditText) this.findViewById(id);
+	return widget.getText().toString();
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
 	setContentView(R.layout.addcontact);
 	Button ok = (Button) findViewById(R.id.addc_ok);
-	//mAccountManager = new AccountManager();
 	ok.setOnClickListener(mOkListener);
 	mService = BeemApplication.getApplication(this).getXmppFacade();
     }
-    
-    private OnClickListener mOkListener = new OnClickListener() {
-	
-	@Override
-	public void onClick(View v) {
-	    boolean valid = true;
-	    if (getWidgetText(R.id.addc_login).length() == 0) {
-		valid = false;
-	    } else {
-		mLogin = getWidgetText(R.id.addc_login);
-	    }
-	    if (getWidgetText(R.id.addc_alias).length() == 0) {
-		valid = false;
-	    } else {
-		mAlias = getWidgetText(R.id.addc_alias);
-	    }
-	    if (getWidgetText(R.id.addc_group).length() == 0) {
-		valid = false;
-	    } else {
-		mGroup.add(getWidgetText(R.id.addc_group));
-	    }
-	    if (valid) {
-		try {
-		    mService.getRoster().addContact(mLogin, mAlias, (String[])mGroup.toArray(new String[mGroup.size()]));
-		    Toast.makeText(AddContact.this, getString(R.string.AddCContactAdded),
-	                    Toast.LENGTH_SHORT).show();
-		    finish();
-		} catch (RemoteException e) {
-		    Toast.makeText(AddContact.this, e.getMessage(),
-	                    Toast.LENGTH_SHORT).show();
-		    e.printStackTrace();
-		}
-		setResult(RESULT_OK);
-	    } else {
-		Toast.makeText(AddContact.this, getString(R.string.AddCBadForm),
-                    Toast.LENGTH_SHORT).show();
-		setResult(RESULT_CANCELED);
-	    }
-	    
-	}
-    };
-    
-    private String getWidgetText(int id) {
-	EditText widget = (EditText) this.findViewById(id);
-	return widget.getText().toString();
-    }
 }
--- a/src/com/beem/project/beem/ui/ChangeStatus.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/ChangeStatus.java	Fri May 29 20:34:30 2009 +0200
@@ -23,43 +23,134 @@
 import com.beem.project.beem.utils.Status;
 
 public class ChangeStatus extends Activity {
-    private TextView mStatusText;
-    private Button mOk;
-    private Button mClear;
-    private Handler mHandler;
-    private BeemApplication mBeemApplication;
-    private IXmppFacade mService = null;
-    private Spinner mSpinner;
-    private static final String[] STATUS = { "Available for chat", "Available", "Busy", "Away", "Unavailable",
-	"Disconnected" };
-    private static final int DISCONNECTED_IDX = 5;
-    private static final int AVAILABLE_FOR_CHAT_IDX = 0;
-    private static final int AVAILABLE_IDX = 1;
-    private static final int BUSY_IDX = 2;
-    private static final int AWAY_IDX = 3;
-    private static final int UNAVAILABLE_IDX = 4;
-    private SharedPreferences mSettings;
-    private ArrayAdapter<String> mAdapter;
-    private Toast mToast;
-    private static Integer nb = 0;
+
+    private TextView              mStatusText;
+    private Button                mOk;
+    private Button                mClear;
+    private Handler               mHandler;
+    private BeemApplication       mBeemApplication;
+    private IXmppFacade           mService               = null;
+    private Spinner               mSpinner;
+    private static final String[] STATUS                 = { "Available for chat", "Available", "Busy", "Away",
+	    "Unavailable", "Disconnected"               };
+    private static final int      DISCONNECTED_IDX       = 5;
+    private static final int      AVAILABLE_FOR_CHAT_IDX = 0;
+    private static final int      AVAILABLE_IDX          = 1;
+    private static final int      BUSY_IDX               = 2;
+    private static final int      AWAY_IDX               = 3;
+    private static final int      UNAVAILABLE_IDX        = 4;
+    private SharedPreferences     mSettings;
+    private ArrayAdapter<String>  mAdapter;
+    private Toast                 mToast;
+    private static Integer        nb                     = 0;
+
+    private final OnClickListener       mOnClickOk             = new OnClickListener() {
+
+	                                                     public void onClick(View v) {
+		                                                 if (v == mOk) {
+		                                                     if (textHasChanged() || statusHasChanged()) {
+			                                                 String msg = mStatusText.getText().toString();
+			                                                 int status = getStatusForService((String) mSpinner
+			                                                         .getSelectedItem());
+			                                                 Editor edit = mSettings.edit();
+			                                                 edit
+			                                                         .putString(
+			                                                                 getString(R.string.PreferenceStatusText),
+			                                                                 msg);
+			                                                 edit.putInt(
+			                                                         getString(R.string.PreferenceStatus),
+			                                                         mSpinner.getSelectedItemPosition());
+			                                                 edit.commit();
+			                                                 if (status == Status.CONTACT_STATUS_DISCONNECT) {
+			                                                     stopService(new Intent(ChangeStatus.this,
+			                                                             BeemService.class));
+			                                                 } else {
+			                                                     try {
+				                                                 mService.changeStatus(status, msg
+				                                                         .toString());
+			                                                     } catch (RemoteException e) {
+				                                                 // TODO
+				                                                 // Auto-generated
+				                                                 // catch block
+				                                                 e.printStackTrace();
+			                                                     }
+			                                                     mToast.show();
+			                                                 }
+		                                                     }
+		                                                     ChangeStatus.this.finish();
+		                                                 } else if (v == mClear) {
+		                                                     mStatusText.setText(null);
+		                                                 }
+
+	                                                     }
+
+	                                                     private boolean statusHasChanged() {
+		                                                 return (mSettings.getInt(
+		                                                         getString(R.string.PreferenceStatus), 0) != mSpinner
+		                                                         .getSelectedItemPosition());
+	                                                     }
+
+	                                                     private boolean textHasChanged() {
+		                                                 return (!mStatusText
+		                                                         .getText()
+		                                                         .toString()
+		                                                         .equals(
+		                                                                 getPreferenceString(R.string.PreferenceStatusText)));
+	                                                     }
+	                                                 };
+
+    private int getPreferenceStatusIndex() {
+	return mSettings.getInt(getString(R.string.PreferenceStatus), 0);
+    }
+
+    private String getPreferenceString(int id) {
+	return mSettings.getString(getString(id), "");
+    }
+
+    private int getStatusForService(String item) {
+	int res = Status.CONTACT_STATUS_AVAILABLE;
+	for (int i = 0; i < ChangeStatus.STATUS.length; i++) {
+	    String str = ChangeStatus.STATUS[i];
+	    if (str.equals(item)) {
+		switch (i) {
+		case ChangeStatus.DISCONNECTED_IDX:
+		    return Status.CONTACT_STATUS_DISCONNECT;
+		case ChangeStatus.AVAILABLE_FOR_CHAT_IDX:
+		    return Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT;
+		case ChangeStatus.AVAILABLE_IDX:
+		    return Status.CONTACT_STATUS_AVAILABLE;
+		case ChangeStatus.AWAY_IDX:
+		    return Status.CONTACT_STATUS_AWAY;
+		case ChangeStatus.BUSY_IDX:
+		    return Status.CONTACT_STATUS_BUSY;
+		case ChangeStatus.UNAVAILABLE_IDX:
+		    return Status.CONTACT_STATUS_UNAVAILABLE;
+		default:
+		    res = Status.CONTACT_STATUS_AVAILABLE;
+		    break;
+		}
+	    }
+	}
+	return res;
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
-	
+
 	nb++;
 	Log.i("nb de oncreate changestatus", nb.toString());
 	// Beem Application specific
 	mHandler = new Handler();
 	mBeemApplication = BeemApplication.getApplication(this);
-	
+
 	setContentView(R.layout.changestatus);
 	mStatusText = (TextView) findViewById(R.id.ChangeStatusText);
 	mOk = (Button) findViewById(R.id.ChangeStatusOk);
 	mClear = (Button) findViewById(R.id.ChangeStatusClear);
 	mOk.setOnClickListener(mOnClickOk);
 	mClear.setOnClickListener(mOnClickOk);
-	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	mSettings = getSharedPreferences(getString(R.string.settings_filename), MODE_PRIVATE);
 
 	mSpinner = (Spinner) findViewById(R.id.ChangeStatusSpinner);
 	mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, STATUS);
@@ -70,15 +161,16 @@
     }
 
     @Override
-    protected void onStart() {
-	super.onStart();
-	mBeemApplication.startBeemService();
+    protected void onDestroy() {
+	super.onDestroy();
+	mBeemApplication.unbindBeemService();
     }
 
     @Override
     protected void onResume() {
 	super.onResume();
 	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
+
 	    @Override
 	    public void run() {
 		mService = mBeemApplication.getXmppFacade();
@@ -87,9 +179,9 @@
     }
 
     @Override
-    protected void onDestroy() {
-	super.onDestroy();
-	mBeemApplication.unbindBeemService();
+    protected void onStart() {
+	super.onStart();
+	mBeemApplication.startBeemService();
     }
 
     private void showSettings() {
@@ -97,79 +189,4 @@
 	mSpinner.setSelection(getPreferenceStatusIndex());
     }
 
-    private int getStatusForService(String item) {
-	int res = Status.CONTACT_STATUS_AVAILABLE;
-	for (int i = 0; i < ChangeStatus.STATUS.length; i++) {
-	    String str = ChangeStatus.STATUS[i];
-	    if (str.equals(item)) {
-		switch (i) {
-		    case ChangeStatus.DISCONNECTED_IDX:
-			return Status.CONTACT_STATUS_DISCONNECT;
-		    case ChangeStatus.AVAILABLE_FOR_CHAT_IDX:
-			return Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT;
-		    case ChangeStatus.AVAILABLE_IDX:
-			return Status.CONTACT_STATUS_AVAILABLE;
-		    case ChangeStatus.AWAY_IDX:
-			return Status.CONTACT_STATUS_AWAY;
-		    case ChangeStatus.BUSY_IDX:
-			return Status.CONTACT_STATUS_BUSY;
-		    case ChangeStatus.UNAVAILABLE_IDX:
-			return Status.CONTACT_STATUS_UNAVAILABLE;
-		    default:
-			res = Status.CONTACT_STATUS_AVAILABLE;
-			break;
-		}
-	    }
-	}
-	return res;
-    }
-
-    private String getPreferenceString(int id) {
-	return mSettings.getString(getString(id), "");
-    }
-
-    private int getPreferenceStatusIndex() {
-	return mSettings.getInt(getString(R.string.PreferenceStatus), 0);
-    }
-
-    
-    private OnClickListener mOnClickOk = new OnClickListener() {
-
-	private boolean textHasChanged() {
-	    return (!mStatusText.getText().toString().equals(getPreferenceString(R.string.PreferenceStatusText)));
-	}
-
-	private boolean statusHasChanged() {
-	    return (mSettings.getInt(getString(R.string.PreferenceStatus), 0) != mSpinner.getSelectedItemPosition());
-	}
-
-	public void onClick(View v) {
-	    if (v == mOk) {
-		if (textHasChanged() || statusHasChanged()) {
-		    String msg = mStatusText.getText().toString();
-		    int status = getStatusForService( (String) mSpinner.getSelectedItem());
-		    Editor edit = mSettings.edit();
-		    edit.putString(getString(R.string.PreferenceStatusText), msg);
-		    edit.putInt(getString(R.string.PreferenceStatus), mSpinner.getSelectedItemPosition());
-		    edit.commit();
-		    if (status == Status.CONTACT_STATUS_DISCONNECT) {
-			stopService(new Intent(ChangeStatus.this, BeemService.class));
-		    } else {
-			try {
-			    mService.changeStatus(status, msg.toString());
-			} catch (RemoteException e) {
-			    // TODO Auto-generated catch block
-			    e.printStackTrace();
-			}
-			mToast.show();
-		    }
-		}
-		ChangeStatus.this.finish();
-	    } else if (v == mClear) {
-		mStatusText.setText(null);
-	    }
-
-	}
-    };
-
 }
--- a/src/com/beem/project/beem/ui/ContactDialog.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactDialog.java	Fri May 29 20:34:30 2009 +0200
@@ -1,31 +1,105 @@
 package com.beem.project.beem.ui;
 
+import org.jivesoftware.smack.packet.Presence;
+
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.Intent;
+import android.os.RemoteException;
+import android.util.Log;
 import android.view.View;
 import android.widget.Button;
-import android.widget.TextView;
 
+import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
 import com.beem.project.beem.service.Contact;
+import com.beem.project.beem.service.PresenceAdapter;
+import com.beem.project.beem.service.aidl.IXmppFacade;
 
 public class ContactDialog extends Dialog {
 
-    private Contact mContact;
-    private Context mContext;
+    class aliasListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+
+	    ContactDialogAliasDialog dialog = new ContactDialogAliasDialog(mContext, mContact);
+	    dialog.setOwnerActivity(ContactDialog.this.getOwnerActivity());
+	    dialog.initService();
+	    dialog.show();
+	}
+
+    }
+
+    class chatListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    Activity a = ContactDialog.this.getOwnerActivity();
+	    Intent i = new Intent(mContext, SendIM.class);
+	    i.putExtra("contact", mContact);
+	    a.startActivity(i);
+	    dismiss();
+	}
+
+    }
+
+    class groupListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+
+    }
+
+    class infosListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    // TODO Auto-generated method stub
+	    dismiss();
+	}
+
+    }
+
+    class resendListener implements View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    Presence presencePacket = new Presence(Presence.Type.subscribe);
+	    presencePacket.setTo(mContact.getJID());
+	    try {
+		mService.sendPresencePacket(new PresenceAdapter(presencePacket));
+	    } catch (RemoteException e) {
+		Log.e(TAG, "resend subscription error", e);
+	    }
+	    dismiss();
+	}
+
+    }
+
+    public static final String TAG = "Option Dialog";
+
+    private Contact            mContact;
+
+    private Context            mContext;
+
+    private IXmppFacade        mService;
 
     public ContactDialog(final Context context, Contact curContact) {
 	super(context);
 	mContext = context;
+
 	setContentView(R.layout.contactdialog);
 	mContact = curContact;
 	setTitle(curContact.getJID());
 
 	Button chat = (Button) findViewById(R.id.CDChat);
 	chat.setOnClickListener(new chatListener());
-	Button alias= (Button) findViewById(R.id.CDAlias);
+	Button alias = (Button) findViewById(R.id.CDAlias);
 	alias.setOnClickListener(new aliasListener());
 	Button group = (Button) findViewById(R.id.CDGroup);
 	group.setOnClickListener(new groupListener());
@@ -35,57 +109,8 @@
 	infos.setOnClickListener(new infosListener());
     }
 
-    class chatListener implements View.OnClickListener {
-
-	@Override
-	public void onClick(View v) {
-	    Activity a = ContactDialog.this.getOwnerActivity();
-	    Intent i = new Intent(mContext, SendIM.class);
-	    i.setData(mContact.toUri());
-	    a.startActivity(i);
-	    dismiss();
-	}
-
-    }
-
-    class aliasListener implements View.OnClickListener {
-
-	@Override
-	public void onClick(View v) {
-	    // TODO Auto-generated method stub
-	    dismiss();
-	}
-	
-    }
-    
-    class groupListener implements View.OnClickListener {
-
-	@Override
-	public void onClick(View v) {
-	    // TODO Auto-generated method stub
-	    dismiss();
-	}
-	
-    }
-    
-    class resendListener implements View.OnClickListener {
-
-	@Override
-	public void onClick(View v) {
-	    // TODO Auto-generated method stub
-	    dismiss();
-	}
-	
-    }
-    
-    class infosListener implements View.OnClickListener {
-
-	@Override
-	public void onClick(View v) {
-	    // TODO Auto-generated method stub
-	    dismiss();
-	}
-	
+    public void initService() {
+	mService = BeemApplication.getApplication(ContactDialog.this.getOwnerActivity()).getXmppFacade();
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/ContactDialogAliasDialog.java	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,58 @@
+/**
+ * 
+ */
+package com.beem.project.beem.ui;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.RemoteException;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.Contact;
+import com.beem.project.beem.service.aidl.IXmppFacade;
+
+/**
+ * @author marseille
+ */
+public class ContactDialogAliasDialog extends Dialog {
+
+    @SuppressWarnings("unused")
+    private String      mName;
+    private Contact     mContact;
+    private IXmppFacade mService;
+
+    public ContactDialogAliasDialog(Context context, Contact contact) {
+	super(context);
+	setContentView(R.layout.contactdialogaliasdialog);
+	setTitle("Alias");
+	mContact = contact;
+	EditText nameText = (EditText) findViewById(R.id.CDAliasDialogName);
+	nameText.setText(mContact.getName());
+
+	Button ok = (Button) findViewById(R.id.CDAliasDialogOk);
+	ok.setOnClickListener(new View.OnClickListener() {
+
+	    @Override
+	    public void onClick(View v) {
+		EditText nameText = (EditText) findViewById(R.id.CDAliasDialogName);
+		try {
+		    mService.getRoster().setContactName(mContact.getJID(), nameText.getText().toString());
+		} catch (RemoteException e) {
+		    e.printStackTrace();
+		}
+		dismiss();
+	    }
+
+	});
+    }
+
+    public void initService() {
+	Activity a = ContactDialogAliasDialog.this.getOwnerActivity();
+	mService = BeemApplication.getApplication(a).getXmppFacade();
+    }
+}
--- a/src/com/beem/project/beem/ui/ContactList.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Fri May 29 20:34:30 2009 +0200
@@ -7,15 +7,11 @@
 
 import org.jivesoftware.smack.util.StringUtils;
 
-import android.app.AlertDialog;
-import android.app.Dialog;
 import android.app.ExpandableListActivity;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.database.DataSetObserver;
 import android.graphics.drawable.Drawable;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -31,7 +27,6 @@
 import android.widget.ExpandableListAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
@@ -44,163 +39,213 @@
 
 public class ContactList extends ExpandableListActivity {
 
-    private static final String TAG = "CONTACTLIST_ACT";
-    private static final int PREFERENCECHANGED = 0;
-    private static final String DEFAULT_GROUP = "Default";
-    private IXmppFacade mService = null;
-    private MyExpandableListAdapter mAdapter;
-    private BeemApplication mBeemApplication;
-    private BeemRosterListener mRosterListener;
-    private SharedPreferences mSettings;
-    private IRoster mRoster;
-    private Map<String, List<Contact>> groupMap;
-    private List<String> groupName;
-    private List<Contact> mListContact;
-    private Handler mHandler;
+    private class BeemRosterListener extends IBeemRosterListener.Stub {
 
-    @Override
-    protected void onCreate(Bundle saveBundle) {
-	super.onCreate(saveBundle);
-	mHandler = new Handler();
-	mRosterListener = new BeemRosterListener();
-	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
-	mBeemApplication = BeemApplication.getApplication(this);
-	groupMap = new HashMap<String, List<Contact>>();
-	groupName = new ArrayList<String>();
-	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
-	    @Override
-	    public void run() {
-		mService = mBeemApplication.getXmppFacade();
-		try {
-		    mRoster = mService.getRoster();
-		} catch (RemoteException e1) {
-		    Log.e(TAG, "Get roster failed", e1);
+	@Override
+	public void onEntriesAdded(List<String> addresses) throws RemoteException {
+	    for (String str : addresses) {
+		Contact curContact = mRoster.getContact(str);
+		for (String group : curContact.getGroups()) {
+		    if (!groupMap.containsKey(group)) {
+			groupMap.put(group, new ArrayList<Contact>());
+			groupName.add(group);
+		    }
+		    try {
+			groupMap.get(group).add(curContact);
+		    } catch (NullPointerException e) {
+			Log.e(TAG, "Failed to find group in groupMap", e);
+		    }
 		}
-		if (mRoster != null) {
-		    try {
-			mRoster.addConnectionListener(mRosterListener);
-		    } catch (RemoteException e) {
-			e.printStackTrace();
+	    }
+	    mHandler.post(new Runnable() {
+
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
+	}
+
+	@Override
+	public void onEntriesDeleted(List<String> addresses) throws RemoteException {
+	    for (List<Contact> cList : groupMap.values()) {
+		for (Contact curContact : cList) {
+		    for (String addr : addresses) {
+			if (addr.equals(curContact.getJID())) {
+			    cList.remove(curContact);
+			    if (cList.isEmpty()) {
+				groupMap.values().remove(cList);
+			    }
+			}
 		    }
 		}
-		callbackShowContactList();
 	    }
-	});	
-    }    
+	    mHandler.post(new Runnable() {
+
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
+	}
 
-    @Override
-    protected void onDestroy() {
-	mBeemApplication.unbindBeemService();
-	super.onDestroy();	
-    }
+	@Override
+	public void onEntriesUpdated(List<String> addresses) throws RemoteException {
+	    for (String str : addresses) {
+		Contact curContact = mRoster.getContact(str);
+		for (String group : curContact.getGroups()) {
+		    if (!groupMap.containsKey(group)) {
+			groupMap.put(group, new ArrayList<Contact>());
+			groupName.add(group);
+			groupMap.get(group).add(curContact);
+		    } else {
+			boolean found = false;
+			for (Contact tempContact : groupMap.get(group)) {
+			    if (tempContact.getJID() == str) {
+				curContact = tempContact;
+				found = true;
+				break;
+			    }
+			}
+			if (!found) {
+			    groupMap.get(group).add(curContact);
+			}
+		    }
+		}
+	    }
+	    mHandler.post(new Runnable() {
 
-    private void callbackShowContactList() {
-	if (mRoster != null) {
-	    try {
-		buildContactList(mRoster.getContactList());
-	    } catch (RemoteException e) {
-		e.printStackTrace();
+		@Override
+		public void run() {
+		    mAdapter.changed();
+		}
+	    });
+	}
+
+	@Override
+	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
+	    for (Contact curContact : mListContact) {
+		if (curContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
+		    curContact.setStatus(presence);
+		    mHandler.post(new Runnable() {
+
+			@Override
+			public void run() {
+			    mAdapter.changed();
+			}
+		    });
+		    return;
+		}
 	    }
 	}
-    }
 
-    /**
-     * Callback for menu creation.
-     * @param menu the menu created
-     * @return true on success, false otherwise
-     */
-    @Override
-    public final boolean onCreateOptionsMenu(Menu menu) {
-	super.onCreateOptionsMenu(menu);
-	MenuInflater inflater = getMenuInflater();
-	inflater.inflate(R.menu.contactlistmenu, menu);
-	return true;
-    }
-
-    /**
-     * Callback for menu item selected.
-     * @param item the item selected
-     * @return true on success, false otherwise
-     */
-    @Override
-    public final boolean onOptionsItemSelected(MenuItem item) {
-	switch (item.getItemId()) {
-	    case R.id.account_edit:
-		startActivityForResult(new Intent(ContactList.this, ContactListSettings.class), PREFERENCECHANGED);
-		return true;
-	    case R.id.account_about:
-		Intent t = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.beem-project.com"));
-		startActivity(t);
-		return true;
-	    case R.id.account_create:
-		startActivity(new Intent(ContactList.this, AccountCreation.class));
-		return true;
-	    case R.id.add_contact:
-		startActivity(new Intent(ContactList.this, AddContact.class));
-		return true;
-	    default:
-		return false;
-	}
-    }
-
-    /*
-     * @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition,
-     * long id) { try { } catch (NullPointerException e) { Log.e(TAG, "Child not found", e); return false; } }
-     */
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-	if (requestCode == PREFERENCECHANGED) {
-	    if (resultCode == RESULT_OK) {
-		if (!groupMap.isEmpty())
-		    groupMap.clear();
-		mBeemApplication.stopBeemService();
-	    }
-	}
-    }
-
-    private void buildContactList(List<Contact> listContact) {
-	mListContact = listContact;	
-	for (Contact contact : listContact) {
-	    for (String group : contact.getGroups()) {
-		if (!groupMap.containsKey(group)) {
-		    groupMap.put(group, new ArrayList<Contact>());
-		    groupName.add(group);
-		}
-		try {
-		    if (!groupMap.get(group).contains(contact))
-			groupMap.get(group).add(contact);
-		} catch (NullPointerException e) {
-		    Log.e(TAG, "Failed to find group in groupMap", e);
-		}
-	    }
-	    if (contact.getGroups().isEmpty()) {
-		if (!groupMap.containsKey(DEFAULT_GROUP)) {
-		    groupMap.put(DEFAULT_GROUP, new ArrayList<Contact>());
-		    groupName.add(DEFAULT_GROUP);
-		}
-		groupMap.get(DEFAULT_GROUP).add(contact);
-	    }
-	}
-	mAdapter = new MyExpandableListAdapter();
-	setListAdapter(mAdapter);
     }
 
     private class MyExpandableListAdapter implements ExpandableListAdapter {
 
-	private List<DataSetObserver> observers;
+	class MyOnClickListener implements OnClickListener {
+
+	    private final Contact mContact;
+
+	    public MyOnClickListener(Contact contact) {
+		mContact = contact;
+	    }
+
+	    @Override
+	    public void onClick(View v) {
+		Intent i = new Intent(ContactList.this, SendIM.class);
+		i.setData(mContact.toUri());
+		startActivity(i);
+	    }
+
+	}
+
+	class MyOnLongClickListener implements OnLongClickListener {
+
+	    private final Contact mContact;
+
+	    public MyOnLongClickListener(Contact contact) {
+		mContact = contact;
+	    }
+
+	    @Override
+	    public boolean onLongClick(View v) {
+		createDialog(mContact);
+		return true;
+	    }
+	}
+
+	private final List<DataSetObserver> observers;
 
 	public MyExpandableListAdapter() {
 	    observers = new ArrayList<DataSetObserver>();
 	}
 
+	@Override
+	public boolean areAllItemsEnabled() {
+	    return true;
+	}
+
+	private void bindView(View view, Contact curContact) {
+
+	    if (curContact != null) {
+		ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus);
+		Drawable imageDrawable = null;
+		switch (curContact.getStatus()) {
+		case Status.CONTACT_STATUS_AVAILABLE:
+		    imageDrawable = getResources().getDrawable(R.drawable.online);
+		    break;
+		case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
+		    imageDrawable = getResources().getDrawable(R.drawable.chat);
+		    break;
+		case Status.CONTACT_STATUS_AWAY:
+		    imageDrawable = getResources().getDrawable(R.drawable.away);
+		    break;
+		case Status.CONTACT_STATUS_BUSY:
+		    imageDrawable = getResources().getDrawable(R.drawable.dnd);
+		    break;
+		case Status.CONTACT_STATUS_DISCONNECT:
+		    imageDrawable = getResources().getDrawable(R.drawable.offline);
+		    break;
+		case Status.CONTACT_STATUS_UNAVAILABLE:
+		    imageDrawable = getResources().getDrawable(R.drawable.requested);
+		    break;
+		default:
+		    imageDrawable = getResources().getDrawable(R.drawable.error);
+		    break;
+		}
+		imgV.setImageDrawable(imageDrawable);
+
+		TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
+		if (v != null) {
+		    v.setText(curContact.getName());
+		}
+
+		v = (TextView) view.findViewById(R.id.contactlistmsgperso);
+		if (v != null) {
+		    v.setText(curContact.getMsgState());
+		}
+
+		// TODO: Rajouter l'avatar du contact getAvatar() dans la classe
+		imgV = (ImageView) view.findViewById(R.id.contactlistavatar);
+		if (imgV != null) {
+		    imageDrawable = getResources().getDrawable(R.drawable.avatar);
+		    imgV.setImageDrawable(imageDrawable);
+		}
+	    }
+	}
+
 	public void changed() {
 	    for (DataSetObserver obs : observers) {
 		obs.onChanged();
 	    }
 	}
 
-	@Override
-	public boolean areAllItemsEnabled() {
-	    return true;
+	void createDialog(Contact contact) {
+	    ContactDialog dialogContact = new ContactDialog(ContactList.this, contact);
+	    dialogContact.setOwnerActivity(ContactList.this);
+	    dialogContact.initService();
+	    dialogContact.show();
 	}
 
 	@Override
@@ -224,60 +269,6 @@
 	    return childPosition;
 	}
 
-	void createDialog(Contact contact) {
-	    Dialog dialogContact= new ContactDialog(ContactList.this, contact);
-	    dialogContact.setOwnerActivity(ContactList.this);
-	    dialogContact.show();
-	}
-
-	class MyOnLongClickListener implements OnLongClickListener {
-	    @Override
-	    public boolean onLongClick(View v) {
-		TextView jidTextView = (TextView) v.findViewById(R.id.contactlistpseudo);
-		String jid = jidTextView.getText().toString();
-		for (Contact curContact : mListContact) {
-		    if (jid.equals(curContact.getJID())) {
-			createDialog(curContact);
-			break;
-		    }
-		}
-		return true;
-	    }
-	}
-
-	class MyOnClickListener implements OnClickListener {
-	    @Override
-	    public void onClick(View v) {
-		TextView jidTextView = (TextView) v.findViewById(R.id.contactlistpseudo);
-		String jid = jidTextView.getText().toString();
-		for (Contact curContact : mListContact) {
-		    if (jid.equals(curContact.getJID())) {
-			Intent i = new Intent(ContactList.this, SendIM.class);
-			i.setData(curContact.toUri());
-			startActivity(i);
-			break;
-		    }
-		}
-	    }
-
-	}
-
-	@Override
-	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
-	    ViewGroup parent) {
-	    View v;
-	    if (convertView == null) {
-		v = LayoutInflater.from(ContactList.this).inflate(R.layout.contactlistcontact, null);
-	    } else {
-		v = convertView;
-	    }
-	    bindView(v, groupMap.get(groupName.get(groupPosition)).get(childPosition));
-
-	    v.setOnLongClickListener(new MyOnLongClickListener());
-	    v.setOnClickListener(new MyOnClickListener());
-	    return v;
-	}
-
 	@Override
 	public int getChildrenCount(int groupPosition) {
 	    try {
@@ -289,6 +280,23 @@
 	}
 
 	@Override
+	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
+	        ViewGroup parent) {
+	    View v;
+	    if (convertView == null) {
+		v = LayoutInflater.from(ContactList.this).inflate(R.layout.contactlistcontact, null);
+	    } else {
+		v = convertView;
+	    }
+	    Contact contact = groupMap.get(groupName.get(groupPosition)).get(childPosition);
+	    bindView(v, contact);
+
+	    v.setOnLongClickListener(new MyOnLongClickListener(contact));
+	    v.setOnClickListener(new MyOnClickListener(contact));
+	    return v;
+	}
+
+	@Override
 	public long getCombinedChildId(long groupId, long childId) {
 	    return 1000 * groupId + childId;
 	}
@@ -360,152 +368,150 @@
 	public void unregisterDataSetObserver(DataSetObserver observer) {
 	    observers.remove(observer);
 	}
+    }
 
-	private void bindView(View view, Contact curContact) {
+    private static final String        TAG               = "CONTACTLIST_ACT";
+    private static final int           PREFERENCECHANGED = 0;
+    private static final String        DEFAULT_GROUP     = "Default";
+    private IXmppFacade                mService          = null;
+    private MyExpandableListAdapter    mAdapter;
+    private BeemApplication            mBeemApplication;
+    private BeemRosterListener         mRosterListener;
+    private IRoster                    mRoster;
+    private Map<String, List<Contact>> groupMap;
+    private List<String>               groupName;
+    private List<Contact>              mListContact;
+
+    private Handler                    mHandler;
+
+    @SuppressWarnings("unused")
+    private SharedPreferences          mSettings;
 
-	    if (curContact != null) {
-		ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus);
-		Drawable imageDrawable = null;
-		switch (curContact.getStatus()) {
-		    case Status.CONTACT_STATUS_AVAILABLE:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.online);
-			break;
-		    case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.chat);
-			break;
-		    case Status.CONTACT_STATUS_AWAY:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.away);
-			break;
-		    case Status.CONTACT_STATUS_BUSY:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.dnd);
-			break;
-		    case Status.CONTACT_STATUS_DISCONNECT:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.offline);
-			break;
-		    case Status.CONTACT_STATUS_UNAVAILABLE:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.requested);
-			break;
-		    default:
-			imageDrawable = (Drawable) getResources().getDrawable(R.drawable.error);
-			break;
+    private void buildContactList(List<Contact> listContact) {
+	mListContact = listContact;
+	for (Contact contact : listContact) {
+	    for (String group : contact.getGroups()) {
+		if (!groupMap.containsKey(group)) {
+		    groupMap.put(group, new ArrayList<Contact>());
+		    groupName.add(group);
+		}
+		try {
+		    if (!groupMap.get(group).contains(contact))
+			groupMap.get(group).add(contact);
+		} catch (NullPointerException e) {
+		    Log.e(TAG, "Failed to find group in groupMap", e);
+		}
+	    }
+	    if (contact.getGroups().isEmpty()) {
+		if (!groupMap.containsKey(DEFAULT_GROUP)) {
+		    groupMap.put(DEFAULT_GROUP, new ArrayList<Contact>());
+		    groupName.add(DEFAULT_GROUP);
 		}
-		imgV.setImageDrawable(imageDrawable);
-
-		TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
-		if (v != null) {
-		    v.setText(curContact.getJID());
-		}
+		groupMap.get(DEFAULT_GROUP).add(contact);
+	    }
+	}
+	mAdapter = new MyExpandableListAdapter();
+	setListAdapter(mAdapter);
+    }
 
-		v = (TextView) view.findViewById(R.id.contactlistmsgperso);
-		if (v != null) {
-		    v.setText(curContact.getMsgState());
-		}
+    private void callbackShowContactList() {
+	if (mRoster != null) {
+	    try {
+		buildContactList(mRoster.getContactList());
+	    } catch (RemoteException e) {
+		e.printStackTrace();
+	    }
+	}
+    }
 
-		// TODO: Rajouter l'avatar du contact getAvatar() dans la classe
-		imgV = (ImageView) view.findViewById(R.id.contactlistavatar);
-		if (imgV != null) {
-		    imageDrawable = (Drawable) getResources().getDrawable(R.drawable.avatar);
-		    imgV.setImageDrawable(imageDrawable);
-		}
+    /*
+     * @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
+     * int childPosition, long id) { try { } catch (NullPointerException e) { Log.e(TAG,
+     * "Child not found", e); return false; } }
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+	if (requestCode == PREFERENCECHANGED) {
+	    if (resultCode == RESULT_OK) {
+		if (!groupMap.isEmpty())
+		    groupMap.clear();
+		mBeemApplication.stopBeemService();
 	    }
 	}
     }
 
-    private class BeemRosterListener extends IBeemRosterListener.Stub {
+    @Override
+    protected void onCreate(Bundle saveBundle) {
+	Log.d(getString(R.string.contact_list_tag), "onCreate() started");
+	super.onCreate(saveBundle);
+	mHandler = new Handler();
+	mRosterListener = new BeemRosterListener();
+	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	mBeemApplication = BeemApplication.getApplication(this);
+	groupMap = new HashMap<String, List<Contact>>();
+	groupName = new ArrayList<String>();
+	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
 
-	@Override
-	public void onEntriesAdded(List<String> addresses) throws RemoteException {
-	    for (String str: addresses) {
-		Contact curContact = mRoster.getContact(str);
-		for (String group: curContact.getGroups()) {
-		    if (!groupMap.containsKey(group)) {
-			groupMap.put(group, new ArrayList<Contact>());
-			groupName.add(group);
-		    }
-		    try {
-			groupMap.get(group).add(curContact);
-		    } catch (NullPointerException e) {
-			Log.e(TAG, "Failed to find group in groupMap", e);
-		    }
+	    @Override
+	    public void run() {
+		mService = mBeemApplication.getXmppFacade();
+		try {
+		    mRoster = mService.getRoster();
+		} catch (RemoteException e1) {
+		    Log.e(TAG, "Get roster failed", e1);
 		}
-	    }
-	    mHandler.post(new Runnable() {
-		@Override
-		public void run() {
-		    mAdapter.changed();
-		}
-	    });
-	}
-
-	@Override
-	public void onEntriesDeleted(List<String> addresses) throws RemoteException {
-	    for (List<Contact> cList : groupMap.values()) {
-		for (Contact curContact:cList) {
-		    for (String addr:addresses) {
-			if (addr.equals(curContact.getJID())) {
-			    cList.remove(curContact);
-			    if (cList.isEmpty()) {
-				groupMap.values().remove(cList);
-				}
-			}
+		if (mRoster != null) {
+		    try {
+			mRoster.addConnectionListener(mRosterListener);
+		    } catch (RemoteException e) {
+			e.printStackTrace();
 		    }
 		}
+		callbackShowContactList();
 	    }
-	    mHandler.post(new Runnable() {
-		@Override
-		public void run() {
-		    mAdapter.changed();
-		}
-	    });
-	}
+	});
+	Log.d(getString(R.string.contact_list_tag), "onCreate() ended");
+    }
+
+    /**
+     * Callback for menu creation.
+     * 
+     * @param menu
+     *            the menu created
+     * @return true on success, false otherwise
+     */
+    @Override
+    public final boolean onCreateOptionsMenu(Menu menu) {
+	super.onCreateOptionsMenu(menu);
+	MenuInflater inflater = getMenuInflater();
+	inflater.inflate(R.menu.contact_list, menu);
+	return true;
+    }
 
-	@Override
-	public void onEntriesUpdated(List<String> addresses) throws RemoteException {
-	    for (String str: addresses) {
-		Contact curContact = mRoster.getContact(str);
-		for (String group: curContact.getGroups()) {
-		    if (!groupMap.containsKey(group)) {
-			groupMap.put(group, new ArrayList<Contact>());
-			groupName.add(group);
-			groupMap.get(group).add(curContact);
-		    } else {
-			boolean found = false;
-			for (Contact tempContact:groupMap.get(group)) {
-			    if (tempContact.getJID() == str) {
-				curContact = tempContact;
-				found = true;
-				break ;
-			    }
-			}
-			if (!found) {
-			    groupMap.get(group).add(curContact);
-			}
-		    }
-		}
-	    }
-	    mHandler.post(new Runnable() {
-		@Override
-		public void run() {
-		    mAdapter.changed();
-		}
-	    });
+    @Override
+    protected void onDestroy() {
+	mBeemApplication.unbindBeemService();
+	super.onDestroy();
+    }
+
+    /**
+     * Callback for menu item selected.
+     * 
+     * @param item
+     *            the item selected
+     * @return true on success, false otherwise
+     */
+    @Override
+    public final boolean onOptionsItemSelected(MenuItem item) {
+	switch (item.getItemId()) {
+	case R.id.contact_list_menu_settings:
+	    startActivity(new Intent(this, EditSettings.class));
+	    return true;
+	case R.id.contact_list_menu_add_contact:
+	    startActivity(new Intent(ContactList.this, AddContact.class));
+	    return true;
+	default:
+	    return false;
 	}
-
-	@Override
-	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
-	    for (Contact curContact : mListContact) {
-		if (curContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
-		    curContact.setStatus(presence);
-		    mHandler.post(new Runnable() {
-			@Override
-			public void run() {
-			    mAdapter.changed();
-			}
-		    });
-		    return;
-		}
-	    }
-	}
-
     }
 }
--- a/src/com/beem/project/beem/ui/ContactListSettings.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactListSettings.java	Fri May 29 20:34:30 2009 +0200
@@ -18,10 +18,134 @@
 
 public class ContactListSettings extends Activity {
 
-    public static final int CHANGE = 1;
-    private boolean mIsChanged = false;
-    private SharedPreferences mSettings;
-    private String[] mProxyTypeString;
+    public static final int              CHANGE      = 1;
+    private boolean                      mIsChanged  = false;
+    private SharedPreferences            mSettings;
+    private String[]                     mProxyTypeString;
+
+    private final OnItemSelectedListener mProxyType  = new OnItemSelectedListener() {
+
+	                                                 @Override
+	                                                 public void onItemSelected(AdapterView<?> parent, View arg1,
+	                                                         int arg2, long arg3) {
+		                                             String value = parent.getSelectedItem().toString();
+		                                             LinearLayout ll = (LinearLayout) findViewById(R.id.proxy_layout);
+		                                             SharedPreferences.Editor editor = mSettings.edit();
+		                                             LayoutParams lp = (LayoutParams) ll.getLayoutParams();
+		                                             if (value
+		                                                     .equals(getString(R.string.PreferenceProxyTypeNone))) {
+		                                                 ll.setVisibility(View.INVISIBLE);
+		                                                 lp.height = 0;
+		                                                 ll.setLayoutParams(lp);
+		                                                 editor.putBoolean(
+		                                                         getString(R.string.PreferenceUseProxy), false);
+		                                             } else {
+		                                                 ll.setVisibility(View.VISIBLE);
+		                                                 lp.height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+		                                                 ll.setLayoutParams(lp);
+		                                                 editor.putBoolean(
+		                                                         getString(R.string.PreferenceUseProxy), true);
+		                                             }
+		                                             if (!value
+		                                                     .equals(getPreferenceString(R.string.PreferenceProxyType))) {
+		                                                 editor
+		                                                         .putString(
+		                                                                 getString(R.string.PreferenceProxyType),
+		                                                                 value);
+		                                                 mIsChanged = true;
+		                                             }
+		                                             editor.commit();
+	                                                 }
+
+	                                                 @Override
+	                                                 public void onNothingSelected(AdapterView<?> arg0) {
+	                                                 }
+
+	                                             };
+
+    private final OnClickListener        mOkListener = new OnClickListener() {
+
+	                                                 public void onClick(View v) {
+		                                             SharedPreferences.Editor editor = mSettings.edit();
+
+		                                             if (isChanged(R.id.host, R.string.PreferenceHostKey)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferenceHostKey),
+		                                                         getWidgetText(R.id.host));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (Integer.parseInt(getWidgetText(R.id.port)) != mSettings
+		                                                     .getInt(getString(R.string.PreferencePortKey),
+		                                                             5222)) {
+		                                                 editor.putInt(getString(R.string.PreferencePortKey),
+		                                                         Integer.parseInt(getWidgetText(R.id.port)));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (isChanged(R.id.userid, R.string.PreferenceLoginKey)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferenceLoginKey),
+		                                                         getWidgetText(R.id.userid));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (isChanged(R.id.password,
+		                                                     R.string.PreferencePasswordKey)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferencePasswordKey),
+		                                                         getWidgetText(R.id.password));
+		                                                 mIsChanged = true;
+		                                             }
+
+		                                             if (isChanged(R.id.proxy_host,
+		                                                     R.string.PreferenceProxyHost)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferenceProxyHost),
+		                                                         getWidgetText(R.id.proxy_host));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (Integer.parseInt(getWidgetText(R.id.proxy_port)) != mSettings
+		                                                     .getInt(getString(R.string.PreferenceProxyPort), 0)) {
+		                                                 editor
+		                                                         .putInt(
+		                                                                 getString(R.string.PreferenceProxyPort),
+		                                                                 Integer
+		                                                                         .parseInt(getWidgetText(R.id.proxy_port)));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (isChanged(R.id.proxy_login,
+		                                                     R.string.PreferenceProxyUser)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferenceProxyUser),
+		                                                         getWidgetText(R.id.proxy_login));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (isChanged(R.id.proxy_pwd,
+		                                                     R.string.PreferenceProxyPassword)) {
+		                                                 editor.putString(
+		                                                         getString(R.string.PreferenceProxyPassword),
+		                                                         getWidgetText(R.id.proxy_pwd));
+		                                                 mIsChanged = true;
+		                                             }
+		                                             if (mIsChanged == true) {
+		                                                 editor.commit();
+		                                                 setResult(RESULT_OK);
+		                                             } else
+		                                                 setResult(RESULT_CANCELED);
+		                                             finish();
+	                                                 }
+	                                             };
+
+    private String getPreferenceString(int id) {
+	return mSettings.getString(getString(id), "");
+    }
+
+    private String getWidgetText(int id) {
+	EditText widget = (EditText) this.findViewById(id);
+	return widget.getText().toString();
+    }
+
+    private boolean isChanged(int idEdit, int idPreference) {
+	return (!getWidgetText(idEdit).equals(getPreferenceString(idPreference)));
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -34,11 +158,11 @@
 	String TypeSocks5 = getString(R.string.PreferenceProxyTypeSocks5);
 
 	mProxyTypeString = new String[] { TypeNone, TypeHTTP, TypeSocks4, TypeSocks5 };
-	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	mSettings = getSharedPreferences(getString(R.string.settings_filename), MODE_PRIVATE);
 
 	Spinner sp = (Spinner) findViewById(R.id.proxy_type);
 	ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,
-	    mProxyTypeString);
+	        mProxyTypeString);
 	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 	sp.setAdapter(adapter);
 	for (int i = 0; i < mProxyTypeString.length; ++i)
@@ -52,91 +176,6 @@
 	showSettings();
     }
 
-    private OnItemSelectedListener mProxyType = new OnItemSelectedListener() {
-
-	@Override
-	public void onItemSelected(AdapterView<?> parent, View arg1, int arg2, long arg3) {
-	    String value = parent.getSelectedItem().toString();
-	    LinearLayout ll = (LinearLayout) findViewById(R.id.proxy_layout);
-	    SharedPreferences.Editor editor = mSettings.edit();
-	    LayoutParams lp = (LayoutParams) ll.getLayoutParams();
-	    if (value.equals(getString(R.string.PreferenceProxyTypeNone))) {
-		ll.setVisibility(LinearLayout.INVISIBLE);
-		lp.height = 0;
-		ll.setLayoutParams(lp);
-		editor.putBoolean(getString(R.string.PreferenceUseProxy), false);
-	    } else {
-		ll.setVisibility(LinearLayout.VISIBLE);
-		lp.height = LayoutParams.WRAP_CONTENT;
-		ll.setLayoutParams(lp);
-		editor.putBoolean(getString(R.string.PreferenceUseProxy), true);
-	    }
-	    if (!value.equals(getPreferenceString(R.string.PreferenceProxyType))) {
-		editor.putString(getString(R.string.PreferenceProxyType), value);
-		mIsChanged = true;
-	    }
-	    editor.commit();
-	}
-
-	@Override
-	public void onNothingSelected(AdapterView<?> arg0) {
-	}
-
-    };
-
-    private OnClickListener mOkListener = new OnClickListener() {
-	public void onClick(View v) {
-	    SharedPreferences.Editor editor = mSettings.edit();
-
-	    if (isChanged(R.id.host, R.string.PreferenceHostKey)) {
-		editor.putString(getString(R.string.PreferenceHostKey), getWidgetText(R.id.host));
-		mIsChanged = true;
-	    }
-	    if (Integer.parseInt(getWidgetText(R.id.port)) != mSettings.getInt(getString(R.string.PreferencePortKey),
-		5222)) {
-		editor.putInt(getString(R.string.PreferencePortKey), Integer.parseInt(getWidgetText(R.id.port)));
-		mIsChanged = true;
-	    }
-	    if (isChanged(R.id.userid, R.string.PreferenceLoginKey)) {
-		editor.putString(getString(R.string.PreferenceLoginKey), getWidgetText(R.id.userid));
-		mIsChanged = true;
-	    }
-	    if (isChanged(R.id.password, R.string.PreferencePasswordKey)) {
-		editor.putString(getString(R.string.PreferencePasswordKey), getWidgetText(R.id.password));
-		mIsChanged = true;
-	    }
-
-	    if (isChanged(R.id.proxy_host, R.string.PreferenceProxyHost)) {
-		editor.putString(getString(R.string.PreferenceProxyHost), getWidgetText(R.id.proxy_host));
-		mIsChanged = true;
-	    }
-	    if (Integer.parseInt(getWidgetText(R.id.proxy_port)) != mSettings.getInt(
-		getString(R.string.PreferenceProxyPort), 0)) {
-		editor
-		    .putInt(getString(R.string.PreferenceProxyPort), Integer.parseInt(getWidgetText(R.id.proxy_port)));
-		mIsChanged = true;
-	    }
-	    if (isChanged(R.id.proxy_login, R.string.PreferenceProxyUser)) {
-		editor.putString(getString(R.string.PreferenceProxyUser), getWidgetText(R.id.proxy_login));
-		mIsChanged = true;
-	    }
-	    if (isChanged(R.id.proxy_pwd, R.string.PreferenceProxyPassword)) {
-		editor.putString(getString(R.string.PreferenceProxyPassword), getWidgetText(R.id.proxy_pwd));
-		mIsChanged = true;
-	    }
-	    if (mIsChanged == true) {
-		editor.commit();
-		setResult(RESULT_OK);
-	    } else
-		setResult(RESULT_CANCELED);
-	    finish();
-	}
-    };
-
-    private boolean isChanged(int idEdit, int idPreference) {
-	return (!getWidgetText(idEdit).equals(getPreferenceString(idPreference)));
-    }
-
     private void showSettings() {
 	EditText e = (EditText) findViewById(R.id.host);
 	e.setText(getPreferenceString(R.string.PreferenceHostKey));
@@ -157,13 +196,4 @@
 	e.setText(getPreferenceString(R.string.PreferenceProxyPassword));
     }
 
-    private String getWidgetText(int id) {
-	EditText widget = (EditText) this.findViewById(id);
-	return widget.getText().toString();
-    }
-
-    private String getPreferenceString(int id) {
-	return mSettings.getString(getString(id), "");
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/CreateAccount.java	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,244 @@
+package com.beem.project.beem.ui;
+
+import org.jivesoftware.smack.AccountManager;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.proxy.ProxyInfo;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.beem.project.beem.R;
+
+/**
+ * This class represents an activity which allows the user to create an account on the XMPP server
+ * saved in settings
+ * 
+ * @author dasilvj
+ */
+public class CreateAccount extends Activity {
+
+    private final static boolean DEFAULT_BOOLEAN_VALUE = false;
+    private final static String  DEFAULT_STRING_VALUE  = "";
+    private final static int     DEFAULT_INT_VALUE     = 0;
+
+    private final static String  DEFAULT_XMPP_PORT     = "5222";
+
+    private final static int     NOTIFICATION_DURATION = Toast.LENGTH_SHORT;
+
+    private SharedPreferences    settings              = null;
+    private Button               createAccountButton   = null;
+
+    /**
+     * Check if the fields password and confirm password match
+     * 
+     * @return return true if password & confirm password fields match, else false
+     */
+    private boolean checkPasswords() {
+	final String passwordFieldValue = ((EditText) findViewById(R.id.create_account_password)).getText().toString();
+	final String passwordConfirmFielddValue = ((EditText) findViewById(R.id.create_account_confirm_password))
+	        .getText().toString();
+
+	if (passwordFieldValue.equals(passwordConfirmFielddValue))
+	    return (true);
+	return (false);
+    }
+
+    /**
+     * Create an account on the XMPP server specified in settings
+     */
+    private void createAccount(String username, String password) {
+	XMPPConnection xmppConnection = null;
+	ConnectionConfiguration connectionConfiguration = null;
+
+	if (getRegisteredProxy() != null) {
+	    connectionConfiguration = new ConnectionConfiguration(getRegisteredXMPPServer(), getRegisteredXMPPPort(),
+		    getRegisteredProxy());
+	} else {
+	    connectionConfiguration = new ConnectionConfiguration(getRegisteredXMPPServer(), getRegisteredXMPPPort());
+	}
+	if (getRegisteredXMPPTLSUse())
+	    connectionConfiguration.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
+
+	xmppConnection = new XMPPConnection(connectionConfiguration);
+	try {
+	    xmppConnection.connect();
+	    AccountManager accountManager = new AccountManager(xmppConnection);
+	    accountManager.createAccount(username, password);
+	    Toast toast = Toast.makeText(getApplicationContext(), "Account " + username + " "
+		    + getString(R.string.create_account_successfull_after), NOTIFICATION_DURATION);
+	    toast.show();
+	} catch (XMPPException e) {
+	    Log.e(getString(R.string.create_account_tag), e.getMessage());
+	    createErrorDialog(e.getMessage());
+	}
+	xmppConnection.disconnect();
+    }
+
+    /**
+     * Create a dialog containing an error message
+     * 
+     * @param errMsg
+     *            the error message
+     */
+    private void createErrorDialog(String errMsg) {
+	Log.v(getString(R.string.create_account_tag), errMsg);
+	AlertDialog.Builder builder = new AlertDialog.Builder(this);
+	builder.setTitle(R.string.create_account_err_dialog_title).setMessage(errMsg).setCancelable(false);
+	builder.setNeutralButton(R.string.create_account_close_dialog_button, new DialogInterface.OnClickListener() {
+
+	    @Override
+	    public void onClick(DialogInterface dialog, int which) {
+		dialog.cancel();
+	    }
+	});
+	AlertDialog settingsErrDialog = builder.create();
+	settingsErrDialog.show();
+    }
+
+    /**
+     * Retrive proxy informations from the preferences
+     * 
+     * @return Registered proxy informations
+     */
+    private ProxyInfo getRegisteredProxy() {
+	if (getRegisteredProxyUse()) {
+	    ProxyInfo proxyInfo = new ProxyInfo(getRegisteredProxyType(), getRegisteredProxyServer(),
+		    getRegisteredProxyPort(), getRegisteredProxyUsername(), getRegisteredProxyPassword());
+	    return (proxyInfo);
+	}
+	return (null);
+    }
+
+    /**
+     * Retrieve proxy password from the preferences
+     * 
+     * @return Registered proxy password
+     */
+    private String getRegisteredProxyPassword() {
+	return (settings.getString(getString(R.string.settings_key_proxy_password), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy port from the preferences
+     * 
+     * @return Registered proxy port
+     */
+    private int getRegisteredProxyPort() {
+	return (Integer.parseInt(settings.getString(getString(R.string.settings_key_proxy_port), DEFAULT_STRING_VALUE)));
+    }
+
+    /**
+     * Retrieve proxy server from the preferences
+     * 
+     * @return Registered proxy server
+     */
+    private String getRegisteredProxyServer() {
+	return (settings.getString(getString(R.string.settings_key_proxy_server), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy type from the preferences
+     * 
+     * @return Registered proxy type
+     */
+    private ProxyInfo.ProxyType getRegisteredProxyType() {
+	switch (settings.getInt(getString(R.string.settings_key_proxy_type), DEFAULT_INT_VALUE)) {
+	case 0:
+	    return ProxyInfo.ProxyType.HTTP;
+	case 1:
+	    return ProxyInfo.ProxyType.SOCKS4;
+	case 2:
+	    Log.i(getString(R.string.create_account_tag), "SOCKS5 PROXY");
+	    return ProxyInfo.ProxyType.SOCKS5;
+	default:
+	    return ProxyInfo.ProxyType.NONE;
+	}
+    }
+
+    /**
+     * Retrieve proxy use from the preferences
+     * 
+     * @return Registered proxy use
+     */
+    private boolean getRegisteredProxyUse() {
+	return (settings.getBoolean(getString(R.string.settings_key_proxy_use), DEFAULT_BOOLEAN_VALUE));
+    }
+
+    /**
+     * Retrieve proxy username from the preferences
+     * 
+     * @return Registered proxy username
+     */
+    private String getRegisteredProxyUsername() {
+	return (settings.getString(getString(R.string.settings_key_proxy_username), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve xmpp port from the preferences
+     * 
+     * @return Registered xmpp port
+     */
+    private int getRegisteredXMPPPort() {
+	return (Integer.parseInt(settings.getString(getString(R.string.settings_key_xmpp_port), DEFAULT_XMPP_PORT)));
+    }
+
+    /**
+     * Retrieve xmpp server from the preferences
+     * 
+     * @return Registered xmpp server
+     */
+    private String getRegisteredXMPPServer() {
+	return (settings.getString(getString(R.string.settings_key_xmpp_server), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve TLS use from the preferences
+     * 
+     * @return Registered TLS use
+     */
+    private boolean getRegisteredXMPPTLSUse() {
+	return (settings.getBoolean(getString(R.string.settings_key_xmpp_tls_use), DEFAULT_BOOLEAN_VALUE));
+    }
+
+    /**
+     * Initialize the "Create this account" button which allows the user to create an account
+     */
+    private void initCreateAccountButton() {
+	createAccountButton = (Button) findViewById(R.id.create_account_button);
+	createAccountButton.setOnClickListener(new View.OnClickListener() {
+
+	    public void onClick(View v) {
+		String usernameFieldValue = ((EditText) findViewById(R.id.create_account_username)).getText()
+		        .toString();
+		String passwordFieldValue = ((EditText) findViewById(R.id.create_account_password)).getText()
+		        .toString();
+
+		if (!checkPasswords())
+		    createErrorDialog(getString(R.string.create_account_err_passwords));
+		else
+		    createAccount(usernameFieldValue, passwordFieldValue);
+	    }
+	});
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.create_account);
+	initCreateAccountButton();
+	settings = getSharedPreferences(getString(R.string.settings_filename), MODE_PRIVATE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/EditSettings.java	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,492 @@
+package com.beem.project.beem.ui;
+
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TabHost;
+import android.widget.Toast;
+
+import com.beem.project.beem.R;
+
+/**
+ * This class represents an activity which allows the user to change his account or proxy parameters
+ * 
+ * @author dasilvj
+ */
+public class EditSettings extends Activity {
+
+    private final static String  LOG_MSG_SETTINGS_SAVED              = "Settings saved successfully.";
+    private final static String  LOG_MSG_XMPP_SETTINGS_REGISTERED    = "XMPP Settings has been registered.";
+    private final static String  LOG_MSG_ACCOUNT_SETTINGS_REGISTERED = "Account Settings has been registered.";
+    private final static String  LOG_MSG_PROXY_SETTINGS_REGISTERED   = "Proxy Settings has been registered.";
+
+    private final static boolean DEFAULT_BOOLEAN_VALUE               = false;
+    private final static String  DEFAULT_STRING_VALUE                = "";
+    private final static int     DEFAULT_INT_VALUE                   = 0;
+
+    private final static String  DEFAULT_XMPP_PORT                   = "5222";
+
+    private final static int     NOTIFICATION_DURATION               = Toast.LENGTH_SHORT;
+
+    private SharedPreferences    settings                            = null;
+
+    private EditText             accUsernameField                    = null;
+    private EditText             accPasswordField                    = null;
+
+    private EditText             xmppServerField                     = null;
+    private EditText             xmppPortField                       = null;
+    private CheckBox             xmppUseTLSCheckBox                  = null;
+
+    private CheckBox             proxyUseCheckBox                    = null;
+    private Spinner              proxyTypeSpinner                    = null;
+    private EditText             proxyServerField                    = null;
+    private EditText             proxyPortField                      = null;
+    private EditText             proxyUsernameField                  = null;
+    private EditText             proxyPasswordField                  = null;
+
+    /**
+     * Add a labeled "Account" tab on the tabbed window view passed by parameter
+     * 
+     * @param tHost
+     *            a tabbed window view
+     */
+    private void addAccountTab(TabHost tHost) {
+	TabHost.TabSpec accountTab = tHost.newTabSpec(getString(R.string.settings_tab_tag_account));
+	accountTab.setIndicator(getString(R.string.settings_tab_label_account));
+	accountTab.setContent(R.id.settings_account);
+	tHost.addTab(accountTab);
+    }
+
+    /**
+     * Add a labeled "Proxy" tab on the tabbed window view passed by parameter
+     * 
+     * @param tHost
+     *            a tabbed window view
+     */
+    private void addProxyTab(TabHost tHost) {
+	TabHost.TabSpec proxyTab = tHost.newTabSpec(getString(R.string.settings_tab_tag_proxy));
+	proxyTab.setIndicator(getString(R.string.settings_tab_label_proxy));
+	proxyTab.setContent(R.id.settings_proxy);
+	tHost.addTab(proxyTab);
+    }
+
+    /**
+     * Add a labeled "XMPP" tab on the tabbed window view passed by parameter
+     * 
+     * @param tHost
+     *            a tabbed window view
+     */
+    private void addXMPPTab(TabHost tHost) {
+	TabHost.TabSpec personalTab = tHost.newTabSpec(getString(R.string.settings_tab_tag_xmpp));
+	personalTab.setIndicator(getString(R.string.settings_tab_label_xmpp));
+	personalTab.setContent(R.id.settings_xmpp);
+	tHost.addTab(personalTab);
+    }
+
+    /**
+     * Disable proxy parameters fields
+     */
+    private void disableProxyParameters() {
+	proxyTypeSpinner.setEnabled(false);
+	proxyServerField.setEnabled(false);
+	proxyPortField.setEnabled(false);
+	proxyUsernameField.setEnabled(false);
+	proxyPasswordField.setEnabled(false);
+    }
+
+    private void displayNotification(CharSequence msg) {
+	Toast toast = Toast.makeText(getApplicationContext(), msg, NOTIFICATION_DURATION);
+	toast.show();
+    }
+
+    /**
+     * Enable proxy parameters fields
+     */
+    private void enableProxyParameters() {
+	proxyTypeSpinner.setEnabled(true);
+	proxyServerField.setEnabled(true);
+	proxyPortField.setEnabled(true);
+	proxyUsernameField.setEnabled(true);
+	proxyPasswordField.setEnabled(true);
+    }
+
+    /**
+     * Retrieve the value of a CheckBox
+     * 
+     * @param viewId
+     * @return true if the CheckBox is checked, else false
+     */
+    private boolean getCheckBoxValue(int viewId) {
+	final CheckBox checkBox = (CheckBox) findViewById(viewId);
+	if (checkBox.isChecked())
+	    return (true);
+	return (false);
+    }
+
+    /**
+     * Retrieve account password from the preferences
+     * 
+     * @return Registered account password
+     */
+    private String getRegisteredAccountPassword() {
+	return (settings.getString(getString(R.string.settings_key_account_password), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve account username from the preferences
+     * 
+     * @return Registered account username
+     */
+    private String getRegisteredAccountUsername() {
+	return (settings.getString(getString(R.string.settings_key_account_username), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy password from the preferences
+     * 
+     * @return Registered proxy password
+     */
+    private String getRegisteredProxyPassword() {
+	return (settings.getString(getString(R.string.settings_key_proxy_password), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy port from the preferences
+     * 
+     * @return Registered proxy port
+     */
+    private String getRegisteredProxyPort() {
+	return (settings.getString(getString(R.string.settings_key_proxy_port), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy server from the preferences
+     * 
+     * @return Registered proxy server
+     */
+    private String getRegisteredProxyServer() {
+	return (settings.getString(getString(R.string.settings_key_proxy_server), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve proxy type from the preferences
+     * 
+     * @return Registered proxy type
+     */
+    private int getRegisteredProxyType() {
+	return (settings.getInt(getString(R.string.settings_key_proxy_type), DEFAULT_INT_VALUE));
+    }
+
+    /**
+     * Retrieve proxy use from the preferences
+     * 
+     * @return Registered proxy use
+     */
+    private boolean getRegisteredProxyUse() {
+	return (settings.getBoolean(getString(R.string.settings_key_proxy_use), DEFAULT_BOOLEAN_VALUE));
+    }
+
+    /**
+     * Retrieve proxy username from the preferences
+     * 
+     * @return Registered proxy username
+     */
+    private String getRegisteredProxyUsername() {
+	return (settings.getString(getString(R.string.settings_key_proxy_username), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve xmpp port from the preferences
+     * 
+     * @return Registered xmpp port
+     */
+    private String getRegisteredXMPPPort() {
+	return (settings.getString(getString(R.string.settings_key_xmpp_port), DEFAULT_XMPP_PORT));
+    }
+
+    /**
+     * Retrieve xmpp server from the preferences
+     * 
+     * @return Registered xmpp server
+     */
+    private String getRegisteredXMPPServer() {
+	return (settings.getString(getString(R.string.settings_key_xmpp_server), DEFAULT_STRING_VALUE));
+    }
+
+    /**
+     * Retrieve TLS use from the preferences
+     * 
+     * @return Registered TLS use
+     */
+    private boolean getRegisteredXMPPTLSUse() {
+	return (settings.getBoolean(getString(R.string.settings_key_xmpp_tls_use), DEFAULT_BOOLEAN_VALUE));
+    }
+
+    /**
+     * Initialize all of the components displayed in tabs (EditText fields, CheckBoxes, Spinners...)
+     */
+    private void initFields() {
+	accUsernameField = (EditText) findViewById(R.id.settings_account_username);
+	accPasswordField = (EditText) findViewById(R.id.settings_account_password);
+
+	xmppServerField = (EditText) findViewById(R.id.settings_xmpp_server);
+	xmppPortField = (EditText) findViewById(R.id.settings_xmpp_port);
+	xmppUseTLSCheckBox = (CheckBox) findViewById(R.id.settings_xmpp_use_tls);
+
+	proxyUseCheckBox = (CheckBox) findViewById(R.id.settings_proxy_use);
+	proxyTypeSpinner = (Spinner) findViewById(R.id.settings_proxy_type);
+	proxyServerField = (EditText) findViewById(R.id.settings_proxy_server);
+	proxyPortField = (EditText) findViewById(R.id.settings_proxy_port);
+	proxyUsernameField = (EditText) findViewById(R.id.settings_proxy_username);
+	proxyPasswordField = (EditText) findViewById(R.id.settings_proxy_password);
+    }
+
+    /**
+     * Initialize proxy's types spinner of the proxy tab
+     */
+    private void initProxyTypesSpinner() {
+	ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.proxy_types,
+	        android.R.layout.simple_spinner_item);
+	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+	proxyTypeSpinner.setAdapter(adapter);
+    }
+
+    /**
+     * Initialize the checkbox allowing user to use a proxy
+     */
+    private void initProxyUseCheckBox() {
+	proxyUseCheckBox.setOnClickListener(new OnClickListener() {
+
+	    public void onClick(View v) {
+		if (proxyUseCheckBox.isChecked()) {
+		    enableProxyParameters();
+		} else {
+		    disableProxyParameters();
+		}
+	    }
+	});
+    }
+
+    /**
+     * Initialize "save" buttons allowing user to save settings
+     */
+    private void initSaveButtons() {
+	final ArrayList<Integer> views = new ArrayList<Integer>();
+	Button saveButton = null;
+
+	views.add(R.id.settings_account_button_save);
+	views.add(R.id.settings_proxy_button_save);
+	views.add(R.id.settings_xmpp_button_save);
+
+	for (int i = 0; i < views.size(); i++) {
+	    saveButton = (Button) findViewById(views.get(i));
+	    saveButton.setOnClickListener(new View.OnClickListener() {
+
+		public void onClick(View v) {
+		    saveSettings();
+		}
+	    });
+	}
+    }
+
+    /**
+     * Initialize tabbed window view by adding tabs and setting the default tab
+     */
+    private void initTabbedWindow() {
+	TabHost tHost = (TabHost) this.findViewById(R.id.settings_tab_host);
+	tHost.setup();
+	addAccountTab(tHost);
+	addXMPPTab(tHost);
+	addProxyTab(tHost);
+	tHost.setCurrentTab(0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.edit_settings);
+	initTabbedWindow();
+	initFields();
+	settings = getSharedPreferences(getString(R.string.settings_filename), MODE_PRIVATE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+	MenuInflater mInflater = getMenuInflater();
+	mInflater.inflate(R.menu.edit_settings, menu);
+	return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+	Intent i = null;
+	switch (item.getItemId()) {
+	case R.id.settings_menu_create_account:
+	    i = new Intent(this, CreateAccount.class);
+	    startActivity(i);
+	    return true;
+	case R.id.settings_menu_login:
+	    i = new Intent(this, Login.class);
+	    startActivity(i);
+	    return true;
+	}
+	return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onResume() {
+	super.onResume();
+	refreshAccountTabFields();
+	refreshXMPPTabFields();
+	refreshProxyTabFields();
+
+	if (!proxyUseCheckBox.isChecked())
+	    disableProxyParameters();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onStart() {
+	super.onStart();
+	initProxyTypesSpinner();
+	initProxyUseCheckBox();
+	initSaveButtons();
+    }
+
+    /**
+     * Refresh values of "Account" tab fields
+     */
+    private void refreshAccountTabFields() {
+	accUsernameField.setText(getRegisteredAccountUsername());
+	accPasswordField.setText(getRegisteredAccountPassword());
+    }
+
+    /**
+     * Refresh values of "Account" tab fields
+     */
+    private void refreshProxyTabFields() {
+	proxyUseCheckBox.setChecked(getRegisteredProxyUse());
+	proxyTypeSpinner.setSelection(getRegisteredProxyType());
+	proxyServerField.setText(getRegisteredProxyServer());
+	proxyPortField.setText(getRegisteredProxyPort());
+	proxyUsernameField.setText(getRegisteredProxyUsername());
+	proxyPasswordField.setText(getRegisteredProxyPassword());
+    }
+
+    /**
+     * Refresh values of "Account" tab fields
+     */
+    private void refreshXMPPTabFields() {
+	xmppServerField.setText(getRegisteredXMPPServer());
+	xmppPortField.setText(getRegisteredXMPPPort());
+	xmppUseTLSCheckBox.setChecked(getRegisteredXMPPTLSUse());
+    }
+
+    /**
+     * Register account settings changes in SharedPreferences.Editor object passed by parameter
+     * 
+     * @param settingsEditor
+     */
+    private void registerAccountSettingsChanges(SharedPreferences.Editor settingsEditor) {
+	final String usernameFieldValue = accUsernameField.getText().toString();
+	final String passwordFieldValue = accPasswordField.getText().toString();
+
+	if (getRegisteredAccountUsername().equals(usernameFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_account_username), usernameFieldValue);
+	if (getRegisteredAccountPassword().equals(passwordFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_account_password), passwordFieldValue);
+	Log.i(getString(R.string.edit_settings_tag), LOG_MSG_ACCOUNT_SETTINGS_REGISTERED);
+    }
+
+    /**
+     * Register proxy settings changes in SharedPreferences.Editor object passed by parameter
+     * 
+     * @param settingsEditor
+     */
+    private void registerProxySettingsChanges(SharedPreferences.Editor settingsEditor) {
+	final int proxyTypeFieldValue = proxyTypeSpinner.getSelectedItemPosition();
+	final String serverFieldValue = proxyServerField.getText().toString();
+	final String portFieldValue = proxyPortField.getText().toString();
+	final String usernameFieldValue = proxyUsernameField.getText().toString();
+	final String passwordFieldValue = proxyPasswordField.getText().toString();
+
+	if (getRegisteredProxyType() != proxyTypeFieldValue)
+	    settingsEditor.putInt(getString(R.string.settings_key_proxy_type), proxyTypeFieldValue);
+	if (getRegisteredProxyServer().equals(serverFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_proxy_server), serverFieldValue);
+	if (getRegisteredProxyPort().equals(portFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_proxy_port), portFieldValue);
+	if (getRegisteredProxyUsername().equals(usernameFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_proxy_username), usernameFieldValue);
+	if (getRegisteredProxyPassword().equals(passwordFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_proxy_password), passwordFieldValue);
+	Log.i(getString(R.string.edit_settings_tag), LOG_MSG_PROXY_SETTINGS_REGISTERED);
+    }
+
+    /**
+     * Register XMPP settings changes in SharedPreferences.Editor object passed by parameter
+     * 
+     * @param settingsEditor
+     */
+    private void registerXMPPSettingsChanges(SharedPreferences.Editor settingsEditor) {
+	final boolean tlsUseCheckBoxValue = getCheckBoxValue(R.id.settings_xmpp_use_tls);
+	final String serverFieldValue = xmppServerField.getText().toString();
+	final String portFieldValue = xmppPortField.getText().toString();
+
+	if (getRegisteredXMPPTLSUse() != tlsUseCheckBoxValue)
+	    settingsEditor.putBoolean(getString(R.string.settings_key_xmpp_tls_use), tlsUseCheckBoxValue);
+	if (getRegisteredXMPPServer().equals(serverFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_xmpp_server), serverFieldValue);
+	if (getRegisteredXMPPPort().equals(portFieldValue) == false)
+	    settingsEditor.putString(getString(R.string.settings_key_xmpp_port), portFieldValue);
+	Log.i(getString(R.string.edit_settings_tag), LOG_MSG_XMPP_SETTINGS_REGISTERED);
+    }
+
+    /**
+     * Save settings in shared preferences
+     */
+    private void saveSettings() {
+	final SharedPreferences.Editor settingsEditor = settings.edit();
+	final boolean proxyUseCheckBoxValue = getCheckBoxValue(R.id.settings_proxy_use);
+
+	if (getRegisteredProxyUse() != proxyUseCheckBoxValue)
+	    settingsEditor.putBoolean(getString(R.string.settings_key_proxy_use), proxyUseCheckBoxValue);
+	if (proxyUseCheckBoxValue)
+	    registerProxySettingsChanges(settingsEditor);
+	registerAccountSettingsChanges(settingsEditor);
+	registerXMPPSettingsChanges(settingsEditor);
+
+	if (settingsEditor.commit()) {
+	    displayNotification(getText(R.string.settings_saved_ok));
+	    Log.i(getString(R.string.edit_settings_tag), LOG_MSG_SETTINGS_SAVED);
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/Login.java	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,212 @@
+package com.beem.project.beem.ui;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.aidl.IBeemConnectionListener;
+import com.beem.project.beem.service.aidl.IXmppConnection;
+import com.beem.project.beem.service.aidl.IXmppFacade;
+
+/**
+ * This class represents an activity which allows the user to connect to an XMPP server with his
+ * username/password
+ * 
+ * @author dasilvj
+ */
+public class Login extends Activity {
+
+    private class BeemConnectionListener extends IBeemConnectionListener.Stub {
+
+	private class ErrorRunnable implements Runnable {
+
+	    private final String mErrorMsg;
+
+	    public ErrorRunnable(String errorMsg) {
+		mErrorMsg = errorMsg;
+	    }
+
+	    @Override
+	    public void run() {
+		progressDialog.setMessage(mErrorMsg);
+	    }
+
+	}
+
+	@Override
+	public void connectionClosed() throws RemoteException {
+	    mIsConnected = false;
+	    beemApp.stopBeemService();
+	}
+
+	@Override
+	public void connectionClosedOnError() throws RemoteException {
+	    mIsConnected = false;
+	    beemApp.stopBeemService();
+	}
+
+	@Override
+	public void connectionFailed(String errorMsg) throws RemoteException {
+	    connectionHandler.post(new ErrorRunnable(errorMsg));
+	    beemApp.stopBeemService();
+	    dismissProgressDialog();
+	}
+
+	private void dismissProgressDialog() {
+	    connectionHandler.post(new Runnable() {
+
+		@Override
+		public void run() {
+		    progressDialog.dismiss();
+		}
+	    });
+	}
+
+	@Override
+	public void onConnect() throws RemoteException {
+	    mIsConnected = true;
+	    dismissProgressDialog();
+	    Log.i(getString(R.string.login_tag), "Connected.");
+	    startActivity(new Intent(Login.this, ContactList.class));
+	}
+
+	@Override
+	public void reconnectingIn(int seconds) throws RemoteException {
+
+	}
+
+	@Override
+	public void reconnectionFailed() throws RemoteException {
+	    mIsConnected = false;
+	}
+
+	@Override
+	public void reconnectionSuccessful() throws RemoteException {
+	    mIsConnected = true;
+	}
+    }
+
+    protected static final String   TAG               = "LOG_AS";
+    private static final Intent     SERVICE_INTENT    = new Intent();
+    static {
+	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
+    }
+    private BeemApplication         beemApp           = null;
+    private IXmppConnection         xmppConnection    = null;
+    private IXmppFacade             xmppFacade        = null;
+    private final Handler           connectionHandler = new Handler();
+
+    private ProgressDialog          progressDialog    = null;
+
+    private boolean                 mIsConnected      = false;
+    private final ServiceConnection mServConn         = new ServiceConnection() {
+
+	                                                  @Override
+	                                                  public void onServiceConnected(ComponentName name,
+	                                                          IBinder service) {
+		                                              xmppFacade = IXmppFacade.Stub.asInterface(service);
+		                                              try {
+		                                                  xmppConnection = xmppFacade.createConnection();
+		                                                  xmppConnection
+		                                                          .addConnectionListener(new BeemConnectionListener());
+		                                              } catch (RemoteException e) {
+		                                                  Log.e(getString(R.string.login_tag),
+		                                                          "REMOTE EXCEPTION $" + e.getMessage());
+		                                              }
+	                                                  }
+
+	                                                  @Override
+	                                                  public void onServiceDisconnected(ComponentName name) {
+		                                              xmppFacade = null;
+		                                              mIsConnected = false;
+	                                                  }
+	                                              };
+
+    /**
+     * Create an about "BEEM" dialog
+     */
+    public void createAboutDialog() {
+	AlertDialog.Builder builder = new AlertDialog.Builder(this);
+	builder.setTitle(R.string.login_about_title).setMessage(R.string.login_about_msg).setCancelable(false);
+	builder.setNeutralButton(R.string.login_about_button, new DialogInterface.OnClickListener() {
+
+	    public void onClick(DialogInterface dialog, int whichButton) {
+		dialog.cancel();
+	    }
+	});
+	AlertDialog aboutDialog = builder.create();
+	aboutDialog.show();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+	Log.d(getString(R.string.login_tag), "onCreate() started");
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.login);
+	progressDialog = new ProgressDialog(this);
+	progressDialog.setMessage("Loading. Please wait...");
+	beemApp = BeemApplication.getApplication(this);
+	this.bindService(Login.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
+	if (!mIsConnected)
+	    progressDialog.show();
+	beemApp.startBeemService();
+	Log.d(getString(R.string.login_tag), "onCreate() ended");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+	MenuInflater mInflater = getMenuInflater();
+	mInflater.inflate(R.menu.login, menu);
+	return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onDestroy() {
+	super.onDestroy();
+	this.progressDialog.dismiss();
+	progressDialog = null;
+	this.unbindService(mServConn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+	Intent i = null;
+
+	switch (item.getItemId()) {
+	case R.id.login_menu_settings:
+	    i = new Intent(this, EditSettings.class);
+	    startActivity(i);
+	    return true;
+	case R.id.login_menu_about:
+	    createAboutDialog();
+	    return true;
+	}
+	return false;
+    }
+}
--- a/src/com/beem/project/beem/ui/SendIM.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIM.java	Fri May 29 20:34:30 2009 +0200
@@ -34,289 +34,15 @@
 
 /**
  * This activity class provides the view for instant messaging after selecting a correspondant.
+ * 
  * @author barbu
  */
 
 public class SendIM extends Activity implements OnClickListener, OnKeyListener {
-    private static final String TAG = "SEND_IM";
-    private EditText mToSend;
-    private SendIMDialogSmiley mSmyDialog;
-    private SharedPreferences mSet;
-    private BeemApplication mBeemApplication;
-    private Handler mHandler;
-    private IXmppFacade mService;
-    private Contact mContact;
-    private IChatManager mChatManager;
-    private IChatManagerListener mChatManagerListener;
-    private IMessageListener mMessageListener;
-    private IChat mChat;
-    private TextView mText;
-    private TextView mLogin;
-    private ScrollView mScrolling;
-    private char mSpeak;
-
-    /**
-     * Constructor.
-     */
-    public SendIM() {
-	super();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onCreate(Bundle saveBundle) {
-	super.onCreate(saveBundle);
-	mHandler = new Handler();
-	mChatManagerListener = new OnChatListener();
-	mMessageListener = new OnMessageListener();
-	mBeemApplication = BeemApplication.getApplication(this);
-	setContentView(R.layout.sendim);
-	mToSend = (EditText) findViewById(R.id.userText);
-	mSet = getSharedPreferences("lol", MODE_PRIVATE);
-	mSmyDialog = new SendIMDialogSmiley(this, mSet);
-	mToSend.setOnClickListener(this);
-	mToSend.setOnKeyListener(this);
-	mLogin = (TextView) findViewById(R.id.sendimlogin);
-	// mContact = getIntent().getParcelableExtra("contact");
-	mContact = new Contact(getIntent().getData());
-	setViewHeader();
-	mText = (TextView) findViewById(R.id.sendimlist);
-	mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onStart() {
-	super.onStart();
-	// TODO cancel the notification if any
-	if (mContact == null)
-	    mContact = getIntent().getParcelableExtra("contact");
-	mService = mBeemApplication.getXmppFacade();
-	setViewHeader();
-
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onNewIntent(Intent intent) {
-	super.onNewIntent(intent);
-	mContact = new Contact(intent.getData());
-	setViewHeader();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onResume() {
-	super.onResume();
-	mBeemApplication = BeemApplication.getApplication(this);
-	if (!mBeemApplication.isConnected())
-	    mBeemApplication.startBeemService();
-	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
-
-	    @Override
-	    public void run() {
-		mService = mBeemApplication.getXmppFacade();
-		try {
-		    if (mChatManager == null) {
-			mChatManager = mService.getChatManager();
-			mChatManager.addChatCreationListener(mChatManagerListener);
-		    }
-		    switchChat(mContact);
-		} catch (RemoteException e) {
-		    Log.e(TAG, "Error during chat manager creation", e);
-		}
-	    }
-	});
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onPause() {
-	super.onPause();
-	try {
-	    mChat.setOpen(false);
-	} catch (RemoteException e) {
-	    Log.d(TAG, "Error while closing chat", e);
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onStop() {
-	super.onStop();
-	try {
-	    mChat.setOpen(false);
-	} catch (RemoteException e) {
-	    Log.d(TAG, "mchat open false", e);
-	}
-	mBeemApplication.unbindBeemService();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onDestroy() {
-	super.onDestroy();
-	if (mChatManager != null) {
-	    try {
-		mChatManager.removeChatCreationListener(mChatManagerListener);
-		// TODO trouver quand detruire le chat
-		// mChatManager.destroyChat(mChat);
-	    } catch (RemoteException e) {
-		Log.e(TAG, "mchat manager and SendIM destroy", e);
-	    }
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onClick(View view) {
-	sendText();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean onKey(View v, int keyCode, KeyEvent event) {
-	if (event.getAction() == KeyEvent.ACTION_DOWN) {
-	    switch (keyCode) {
-		case KeyEvent.KEYCODE_DPAD_CENTER:
-		case KeyEvent.KEYCODE_ENTER:
-		    sendText();
-		    return true;
-		default:
-		    return false;
-	    }
-	}
-	return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final boolean onCreateOptionsMenu(Menu menu) {
-	super.onCreateOptionsMenu(menu);
-	MenuInflater inflater = getMenuInflater();
-	inflater.inflate(R.menu.sendimmenu, menu);
-	return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final boolean onOptionsItemSelected(MenuItem item) {
-	switch (item.getItemId()) {
-	    case R.id.sendim_smiley:
-		mSmyDialog.show();
-		return true;
-	    default:
-		return false;
-	}
-    }
-
-    /**
-     * Send a message to the contact over the XMPP connection. Also display it on activity view. TODO : Gerer
-     * l'exception si la connexion se coupe pendant la conversation
-     */
-    private void sendText() {
-	String text = mToSend.getText().toString();
-	if (!text.equals("")) {
-	    Message msg = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
-	    msg.setBody(text);
-	    try {
-		mChat.sendMessage(msg);
-		if (mSpeak != 1)
-		    mText.append(getString(R.string.SendIMYouSay) + text + '\n');
-		else
-		    mText.append(text + "\n");
-		mToSend.setText(null);
-		mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
-		mToSend.requestFocus();
-		mSpeak = 1;
-	    } catch (RemoteException e) {
-		// TODO Auto-generated catch block
-		e.printStackTrace();
-	    }
-	}
-    }
-
-    /**
-     * Change the correspondant of the chat.
-     * @param newContact New contact to chat with
-     * @throws RemoteException if an errors occurs in the connection with the service
-     */
-    private void switchChat(Contact newContact) throws RemoteException {
-	if (mChat != null)
-	    mChat.setOpen(false);
-	mChat = mChatManager.createChat(newContact, mMessageListener);
-	showMessageList(mChat.getMessages());
-	mChat.setOpen(true);
-	mContact = newContact;
-	mToSend.requestFocus();
-    }
-
-    /**
-     * Set the header information in the window.
-     */
-    private void setViewHeader() {
-	Drawable avatar = (Drawable) getResources().getDrawable(R.drawable.avatar);
-	ImageView imgV = (ImageView) findViewById(R.id.sendimavatar);
-	imgV.setImageDrawable(avatar);
-	mLogin = (TextView) findViewById(R.id.sendimlogin);
-	mLogin.setText(mContact.getJID());
-	TextView status = (TextView) findViewById(R.id.sendimstatus);
-	status.setTextSize(12);
-	mLogin.setTextColor(getResources().getColor(R.color.white));
-	String statmsg = mContact.getMsgState();
-	if (statmsg != null)
-	    status.setText(statmsg);
-    }
-
-    /**
-     * Show the message history.
-     * @param messages list of message to display
-     */
-    private void showMessageList(List<Message> messages) {
-	mText.setText("");
-	mSpeak = 0;
-	for (Message message : messages) {
-	    String from = message.getFrom();
-	    if (from == null) {
-		if (mSpeak != 1)
-		    mText.append(getString(R.string.SendIMYouSay));
-		mSpeak = 1;
-	    } else {
-		if (mSpeak != 2) {
-		    String str = String.format(getString(R.string.SendIMSays), from);
-		    mText.append(str);
-		}
-		mSpeak = 2;
-	    }
-	    mText.append(message.getBody() + '\n');
-	}
-	mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
-    }
 
     /**
      * Listener for chat creation. (maybe not necessary)
+     * 
      * @author darisk
      */
     private class OnChatListener extends IChatManagerListener.Stub {
@@ -333,6 +59,7 @@
 
     /**
      * Listener for new chat messages.
+     * 
      * @author darisk
      */
     private class OnMessageListener extends IMessageListener.Stub {
@@ -375,4 +102,288 @@
 	    // Log.d(TAG, "state changed");
 	}
     }
+
+    private static final String  TAG = "SEND_IM";
+    private EditText             mToSend;
+    private SendIMDialogSmiley   mSmyDialog;
+    private SharedPreferences    mSet;
+    private BeemApplication      mBeemApplication;
+    private Handler              mHandler;
+    private IXmppFacade          mService;
+    private Contact              mContact;
+    private IChatManager         mChatManager;
+    private IChatManagerListener mChatManagerListener;
+    private IMessageListener     mMessageListener;
+    private IChat                mChat;
+    private TextView             mText;
+    private TextView             mLogin;
+
+    private ScrollView           mScrolling;
+
+    private char                 mSpeak;
+
+    /**
+     * Constructor.
+     */
+    public SendIM() {
+	super();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onClick(View view) {
+	sendText();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onCreate(Bundle saveBundle) {
+	super.onCreate(saveBundle);
+	mHandler = new Handler();
+	mChatManagerListener = new OnChatListener();
+	mMessageListener = new OnMessageListener();
+	mBeemApplication = BeemApplication.getApplication(this);
+	setContentView(R.layout.sendim);
+	mToSend = (EditText) findViewById(R.id.userText);
+	mSet = getSharedPreferences("lol", MODE_PRIVATE);
+	mSmyDialog = new SendIMDialogSmiley(this, mSet);
+	mToSend.setOnClickListener(this);
+	mToSend.setOnKeyListener(this);
+	mLogin = (TextView) findViewById(R.id.sendimlogin);
+	// mContact = getIntent().getParcelableExtra("contact");
+	mContact = new Contact(getIntent().getData());
+	setViewHeader();
+	mText = (TextView) findViewById(R.id.sendimlist);
+	mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final boolean onCreateOptionsMenu(Menu menu) {
+	super.onCreateOptionsMenu(menu);
+	MenuInflater inflater = getMenuInflater();
+	inflater.inflate(R.menu.sendimmenu, menu);
+	return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onDestroy() {
+	super.onDestroy();
+	if (mChatManager != null) {
+	    try {
+		mChatManager.removeChatCreationListener(mChatManagerListener);
+		// TODO trouver quand detruire le chat
+		// mChatManager.destroyChat(mChat);
+	    } catch (RemoteException e) {
+		Log.e(TAG, "mchat manager and SendIM destroy", e);
+	    }
+	}
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+	if (event.getAction() == KeyEvent.ACTION_DOWN) {
+	    switch (keyCode) {
+	    case KeyEvent.KEYCODE_DPAD_CENTER:
+	    case KeyEvent.KEYCODE_ENTER:
+		sendText();
+		return true;
+	    default:
+		return false;
+	    }
+	}
+	return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onNewIntent(Intent intent) {
+	super.onNewIntent(intent);
+	mContact = new Contact(intent.getData());
+	setViewHeader();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final boolean onOptionsItemSelected(MenuItem item) {
+	switch (item.getItemId()) {
+	case R.id.sendim_smiley:
+	    mSmyDialog.show();
+	    return true;
+	default:
+	    return false;
+	}
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onPause() {
+	super.onPause();
+	try {
+	    mChat.setOpen(false);
+	} catch (RemoteException e) {
+	    Log.d(TAG, "Error while closing chat", e);
+	}
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onResume() {
+	super.onResume();
+	mBeemApplication = BeemApplication.getApplication(this);
+	if (!mBeemApplication.isConnected())
+	    mBeemApplication.startBeemService();
+	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
+
+	    @Override
+	    public void run() {
+		mService = mBeemApplication.getXmppFacade();
+		try {
+		    if (mChatManager == null) {
+			mChatManager = mService.getChatManager();
+			mChatManager.addChatCreationListener(mChatManagerListener);
+		    }
+		    switchChat(mContact);
+		} catch (RemoteException e) {
+		    Log.e(TAG, "Error during chat manager creation", e);
+		}
+	    }
+	});
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onStart() {
+	super.onStart();
+	// TODO cancel the notification if any
+	if (mContact == null)
+	    mContact = getIntent().getParcelableExtra("contact");
+	mService = mBeemApplication.getXmppFacade();
+	setViewHeader();
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onStop() {
+	super.onStop();
+	try {
+	    mChat.setOpen(false);
+	} catch (RemoteException e) {
+	    Log.d(TAG, "mchat open false", e);
+	}
+	mBeemApplication.unbindBeemService();
+    }
+
+    /**
+     * Send a message to the contact over the XMPP connection. Also display it on activity view.
+     * TODO : Gerer l'exception si la connexion se coupe pendant la conversation
+     */
+    private void sendText() {
+	String text = mToSend.getText().toString();
+	if (!text.equals("")) {
+	    Message msg = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
+	    msg.setBody(text);
+	    try {
+		mChat.sendMessage(msg);
+		if (mSpeak != 1)
+		    mText.append(getString(R.string.SendIMYouSay) + text + '\n');
+		else
+		    mText.append(text + "\n");
+		mToSend.setText(null);
+		mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
+		mToSend.requestFocus();
+		mSpeak = 1;
+	    } catch (RemoteException e) {
+		// TODO Auto-generated catch block
+		e.printStackTrace();
+	    }
+	}
+    }
+
+    /**
+     * Set the header information in the window.
+     */
+    private void setViewHeader() {
+	Drawable avatar = getResources().getDrawable(R.drawable.avatar);
+	ImageView imgV = (ImageView) findViewById(R.id.sendimavatar);
+	imgV.setImageDrawable(avatar);
+	mLogin = (TextView) findViewById(R.id.sendimlogin);
+	mLogin.setText(mContact.getJID());
+	TextView status = (TextView) findViewById(R.id.sendimstatus);
+	status.setTextSize(12);
+	mLogin.setTextColor(getResources().getColor(R.color.white));
+	String statmsg = mContact.getMsgState();
+	if (statmsg != null)
+	    status.setText(statmsg);
+    }
+
+    /**
+     * Show the message history.
+     * 
+     * @param messages
+     *            list of message to display
+     */
+    private void showMessageList(List<Message> messages) {
+	mText.setText("");
+	mSpeak = 0;
+	for (Message message : messages) {
+	    String from = message.getFrom();
+	    if (from == null) {
+		if (mSpeak != 1)
+		    mText.append(getString(R.string.SendIMYouSay));
+		mSpeak = 1;
+	    } else {
+		if (mSpeak != 2) {
+		    String str = String.format(getString(R.string.SendIMSays), from);
+		    mText.append(str);
+		}
+		mSpeak = 2;
+	    }
+	    mText.append(message.getBody() + '\n');
+	}
+	mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
+    }
+
+    /**
+     * Change the correspondant of the chat.
+     * 
+     * @param newContact
+     *            New contact to chat with
+     * @throws RemoteException
+     *             if an errors occurs in the connection with the service
+     */
+    private void switchChat(Contact newContact) throws RemoteException {
+	if (mChat != null)
+	    mChat.setOpen(false);
+	mChat = mChatManager.createChat(newContact, mMessageListener);
+	showMessageList(mChat.getMessages());
+	mChat.setOpen(true);
+	mContact = newContact;
+	mToSend.requestFocus();
+    }
 }
--- a/src/com/beem/project/beem/ui/SendIMDialogSmiley.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIMDialogSmiley.java	Fri May 29 20:34:30 2009 +0200
@@ -1,12 +1,15 @@
 package com.beem.project.beem.ui;
 
-import com.beem.project.beem.R;
-
 import android.app.Dialog;
 import android.content.SharedPreferences;
 
+import com.beem.project.beem.R;
+
 public class SendIMDialogSmiley extends Dialog {
-    private SendIM mSendIM;
+
+    @SuppressWarnings("unused")
+    private SendIM            mSendIM;
+    @SuppressWarnings("unused")
     private SharedPreferences mSet;
 
     public SendIMDialogSmiley(SendIM sendim, SharedPreferences settings) {
--- a/src/com/beem/project/beem/utils/PresenceType.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/utils/PresenceType.java	Fri May 29 20:34:30 2009 +0200
@@ -7,35 +7,34 @@
 
 /**
  * @author nikita
- *
  */
 public class PresenceType {
 
     /**
      * The user is available to receive messages (default).
      */
-    public static final int AVAILABLE = 100;
+    public static final int AVAILABLE    = 100;
 
     /**
      * The user is unavailable to receive messages.
      */
-    public static final int UNAVAILABLE = 200;
+    public static final int UNAVAILABLE  = 200;
 
     /**
      * Request subscription to recipient's presence.
      */
 
-    public static final int SUBSCRIBE = 300;
+    public static final int SUBSCRIBE    = 300;
 
     /**
      * Grant subscription to sender's presence.
      */
-    public static final int SUBSCRIBED = 400;
+    public static final int SUBSCRIBED   = 400;
 
     /**
      * Request removal of subscription to sender's presence.
      */
-    public static final int UNSUBSCRIBE = 500;
+    public static final int UNSUBSCRIBE  = 500;
 
     /**
      * Grant removal of subscription to sender's presence.
@@ -45,72 +44,76 @@
     /**
      * The presence packet contains an error message.
      */
-    public static final int ERROR = 701;
+    public static final int ERROR        = 701;
 
     /**
      * Get the presence type from a presence packet.
-     * @param presence the presence type
+     * 
+     * @param presence
+     *            the presence type
      */
     public static int getPresenceType(Presence presence) {
 	int res = PresenceType.ERROR;
 	switch (presence.getType()) {
-	    case available:
-		res = PresenceType.AVAILABLE;
-		break;
-	    case unavailable:
-		res = PresenceType.UNAVAILABLE;
-		break;
-	    case subscribe:
-		res = PresenceType.SUBSCRIBE;
-		break;
-	    case subscribed:
-		res = PresenceType.SUBSCRIBED;
-		break;
-	    case unsubscribe:
-		res = PresenceType.UNSUBSCRIBE;
-		break;
-	    case unsubscribed:
-		res = PresenceType.UNSUBSCRIBED;
-		break;
-	    case error:
-	    default:
-		res = PresenceType.ERROR;
-	};
+	case available:
+	    res = PresenceType.AVAILABLE;
+	    break;
+	case unavailable:
+	    res = PresenceType.UNAVAILABLE;
+	    break;
+	case subscribe:
+	    res = PresenceType.SUBSCRIBE;
+	    break;
+	case subscribed:
+	    res = PresenceType.SUBSCRIBED;
+	    break;
+	case unsubscribe:
+	    res = PresenceType.UNSUBSCRIBE;
+	    break;
+	case unsubscribed:
+	    res = PresenceType.UNSUBSCRIBED;
+	    break;
+	case error:
+	default:
+	    res = PresenceType.ERROR;
+	}
+	;
 	return res;
     }
-    
+
     /**
      * Get the smack presence mode for a status
-     * @param status the status in beem
-     * @return the presence mode to use in presence packet
-     * 		or null if there is no mode to use
+     * 
+     * @param status
+     *            the status in beem
+     * @return the presence mode to use in presence packet or null if there is no mode to use
      */
-    public static Presence.Type getPresenceTypeFrom(int type){
+    public static Presence.Type getPresenceTypeFrom(int type) {
 	Presence.Type res;
 	switch (type) {
-	    case AVAILABLE:
-		res = Presence.Type.available;
-		break;
-	    case UNAVAILABLE:
-		res = Presence.Type.unavailable;		
-		break;
-	    case SUBSCRIBE:
-		res = Presence.Type.subscribe;
-		break;
-	    case SUBSCRIBED:
-		res = Presence.Type.subscribed;
-		break;
-	    case UNSUBSCRIBE:
-		res = Presence.Type.unsubscribe;
-		break;
-	    case UNSUBSCRIBED:
-		res = Presence.Type.unsubscribed;
-		break;
-	    case ERROR:
-		res = Presence.Type.error;
-		break;
-	    default:
-		return null;
+	case AVAILABLE:
+	    res = Presence.Type.available;
+	    break;
+	case UNAVAILABLE:
+	    res = Presence.Type.unavailable;
+	    break;
+	case SUBSCRIBE:
+	    res = Presence.Type.subscribe;
+	    break;
+	case SUBSCRIBED:
+	    res = Presence.Type.subscribed;
+	    break;
+	case UNSUBSCRIBE:
+	    res = Presence.Type.unsubscribe;
+	    break;
+	case UNSUBSCRIBED:
+	    res = Presence.Type.unsubscribed;
+	    break;
+	case ERROR:
+	    res = Presence.Type.error;
+	    break;
+	default:
+	    return null;
 	}
 	return res;
     }
--- a/src/com/beem/project/beem/utils/Status.java	Sat May 23 20:59:27 2009 +0200
+++ b/src/com/beem/project/beem/utils/Status.java	Fri May 29 20:34:30 2009 +0200
@@ -14,27 +14,27 @@
     /**
      * Status of a disconnected contact.
      */
-    public static final int CONTACT_STATUS_DISCONNECT = 100;
+    public static final int CONTACT_STATUS_DISCONNECT         = 100;
 
     /**
      * Status of a unavailable (long away) contact.
      */
-    public static final int CONTACT_STATUS_UNAVAILABLE = 200;
+    public static final int CONTACT_STATUS_UNAVAILABLE        = 200;
 
     /**
      * Status of a away contact.
      */
-    public static final int CONTACT_STATUS_AWAY = 300;
+    public static final int CONTACT_STATUS_AWAY               = 300;
 
     /**
      * Status of a busy contact.
      */
-    public static final int CONTACT_STATUS_BUSY = 400;
+    public static final int CONTACT_STATUS_BUSY               = 400;
 
     /**
      * Status of a available contact.
      */
-    public static final int CONTACT_STATUS_AVAILABLE = 500;
+    public static final int CONTACT_STATUS_AVAILABLE          = 500;
 
     /**
      * Status of a available for chat contact.
@@ -42,8 +42,41 @@
     public static final int CONTACT_STATUS_AVAILABLE_FOR_CHAT = 600;
 
     /**
+     * Get the smack presence mode for a status
+     * 
+     * @param status
+     *            the status in beem
+     * @return the presence mode to use in presence packet or null if there is no mode to use
+     */
+    public static Presence.Mode getPresenceModeFromStatus(int status) {
+	Presence.Mode res;
+	switch (status) {
+	case CONTACT_STATUS_AVAILABLE:
+	    res = Presence.Mode.available;
+	    break;
+	case CONTACT_STATUS_AVAILABLE_FOR_CHAT:
+	    res = Presence.Mode.chat;
+	    break;
+	case CONTACT_STATUS_AWAY:
+	    res = Presence.Mode.away;
+	    break;
+	case CONTACT_STATUS_BUSY:
+	    res = Presence.Mode.dnd;
+	    break;
+	case CONTACT_STATUS_UNAVAILABLE:
+	    res = Presence.Mode.xa;
+	    break;
+	default:
+	    return null;
+	}
+	return res;
+    }
+
+    /**
      * Get the status of from a presence packet.
-     * @param presence the presence containing status
+     * 
+     * @param presence
+     *            the presence containing status
      */
     public static int getStatusFromPresence(Presence presence) {
 	int res = Status.CONTACT_STATUS_DISCONNECT;
@@ -55,58 +88,28 @@
 		res = Status.CONTACT_STATUS_AVAILABLE;
 	    } else {
 		switch (mode) {
-		    case available:
-			res = Status.CONTACT_STATUS_AVAILABLE;
-			break;
-		    case away:
-			res = Status.CONTACT_STATUS_AWAY;
-			break;
-		    case chat:
-			res = Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT;
-			break;
-		    case dnd:
-			res = Status.CONTACT_STATUS_BUSY;
-			break;
-		    case xa:
-			res = Status.CONTACT_STATUS_UNAVAILABLE;
-			break;
-		    default:
-			res = Status.CONTACT_STATUS_DISCONNECT;
-			break;
+		case available:
+		    res = Status.CONTACT_STATUS_AVAILABLE;
+		    break;
+		case away:
+		    res = Status.CONTACT_STATUS_AWAY;
+		    break;
+		case chat:
+		    res = Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT;
+		    break;
+		case dnd:
+		    res = Status.CONTACT_STATUS_BUSY;
+		    break;
+		case xa:
+		    res = Status.CONTACT_STATUS_UNAVAILABLE;
+		    break;
+		default:
+		    res = Status.CONTACT_STATUS_DISCONNECT;
+		    break;
 		}
 	    }
 	}
 	return res;
     }
-    
-    /**
-     * Get the smack presence mode for a status
-     * @param status the status in beem
-     * @return the presence mode to use in presence packet
-     * 		or null if there is no mode to use
-     */
-    public static Presence.Mode getPresenceModeFromStatus(int status){
-	Presence.Mode res;
-	switch (status) {
-	    case CONTACT_STATUS_AVAILABLE:
-		res = Presence.Mode.available;
-		break;
-	    case CONTACT_STATUS_AVAILABLE_FOR_CHAT:
-		res = Presence.Mode.chat;		
-		break;
-	    case CONTACT_STATUS_AWAY:
-		res = Presence.Mode.away;
-		break;
-	    case CONTACT_STATUS_BUSY:
-		res = Presence.Mode.dnd;
-		break;
-	    case CONTACT_STATUS_UNAVAILABLE:
-		res = Presence.Mode.xa;
-		break;
-	    default:
-		return null;
-	}
-	return res;
-    }
-    
+
 }
--- a/src/jlibrtp/AppCallerThread.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.util.Enumeration;
-
-/**
- * The purpose of this thread is to check whether there are packets ready from 
- * any participants.
- * 
- * It should sleep when not in use, and be woken up by a condition variable.
- * 
- * Optionally, if we do jitter-control, the condition variable should have a max waiting period 
- * equal to how often we need to push data.
- * 
- * @author Arne Kepp
- */
-public class AppCallerThread extends Thread {
-	/**  The parent RTP Session */
-	RTPSession rtpSession;
-	/**  The applications interface, where the callback methods are called */
-	RTPAppIntf appl;
-	
-	/**
-	 * Instatiates the AppCallerThread
-	 * 
-	 * @param session the RTPSession with participants etc
-	 * @param rtpApp the interface to which data is given
-	 */
-	protected AppCallerThread(RTPSession session, RTPAppIntf rtpApp) {
-		rtpSession = session;
-		appl = rtpApp;
-		if(RTPSession.rtpDebugLevel > 1) {
-			System.out.println("<-> AppCallerThread created");
-		}  
-	}
-	
-	/**
-	 * The AppCallerThread will run in this loop until the RTPSession
-	 * is terminated.
-	 * 
-	 * Whenever an RTP packet is received it will loop over the
-	 * participants to check for packet buffers that have available
-	 * frame.
-	 */
-	public void run() {
-		if(RTPSession.rtpDebugLevel > 3) {
-			System.out.println("-> AppCallerThread.run()");
-		}
-		
-		while(rtpSession.endSession == false) {
-			
-			rtpSession.pktBufLock.lock();
-		    try {
-				if(RTPSession.rtpDebugLevel > 4) {
-					System.out.println("<-> AppCallerThread going to Sleep");
-				}
-				
-				try { rtpSession.pktBufDataReady.await(); } 
-					catch (Exception e) { System.out.println("AppCallerThread:" + e.getMessage());}
-					
-		    	// Next loop over all participants and check whether they have anything for us.
-				Enumeration<Participant> enu = rtpSession.partDb.getParticipants();
-				
-				while(enu.hasMoreElements()) {
-					Participant p = enu.nextElement(); 
-					
-					boolean done = false;
-					//System.out.println(p.ssrc + " " + !done +" " + p.rtpAddress 
-					//		+ " " + rtpSession.naiveReception + " " + p.pktBuffer);
-					//System.out.println("done: " + done + "  p.unexpected: " + p.unexpected);
-					while(!done && (!p.unexpected || rtpSession.naiveReception) 
-							&& p.pktBuffer != null && p.pktBuffer.length > 0) {
-
-						DataFrame aFrame = p.pktBuffer.popOldestFrame();
-						if(aFrame == null) {
-							done = true;
-						} else {
-							appl.receiveData(aFrame, p);
-						}
-					}
-				}
-		    
-		     } finally {
-		       rtpSession.pktBufLock.unlock();
-		     }
-			
-		}
-		if(RTPSession.rtpDebugLevel > 3) {
-			System.out.println("<- AppCallerThread.run() terminating");
-		}  
-	}
-
-}
--- a/src/jlibrtp/CompRtcpPkt.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-import java.util.*;
-import java.net.InetSocketAddress;
-
-/**
- * Compound RTCP packet class.
- * 
- * It basically holds a list of packets. This list can either be constructed
- * by providing a byte[] of a compound packet, or by adding individual packets.
- * 
- * Upon encode(), the packet will call encode on all the added packets.
- * 
- * problem == 0 indicates the parsing succeeded.
- * 
- * 
- * @author Arne Kepp
- */
-
-public class CompRtcpPkt {
-	/** Problem indicator, negative values denote packet type that cause problem */
-	protected int problem = 0;
-	/** Stores the different subclasses of RtcpPkt that make up the compound packet */
-	protected LinkedList<RtcpPkt> rtcpPkts = new LinkedList<RtcpPkt>();
-	
-	/**
-	 * Instantiates an empty Compound RTCP packet to which you can add RTCP packets
-	 */
-	protected CompRtcpPkt() {
-		// Will have to add packets directly to rtcpPkts.
-		if(RTPSession.rtpDebugLevel > 7) {
-			System.out.println("<-> CompRtcpPkt()");
-		}
-	}
-	
-	/**
-	 * Add a RTCP packet to the compound packet. Pakcets are added in order,
-	 * so you have to ensure that a Sender Report or Receiver Report is 
-	 * added first.
-	 * 
-	 * @param aPkt the packet to be added
-	 */
-	protected void addPacket(RtcpPkt aPkt) {
-		if(RTPSession.rtpDebugLevel > 11) {
-			System.out.println("  <-> CompRtcpPkt.addPacket( "+ aPkt.getClass() + " )");
-		}
-		
-		if(aPkt.problem == 0) {
-			rtcpPkts.add(aPkt);
-		} else {
-			this.problem = aPkt.problem;
-		}
-	}
-	
-	/**
-	 * Picks a received Compound RTCP packet apart.
-	 * 
-	 * Only SDES packets are processed directly, other packets are
-	 * parsed and put into aComptRtcpPkt.rtcpPkts, but not 
-	 * 
-	 * Check the aComptRtcpPkt.problem , if the value is non-zero
-	 * the packets should probably be discarded.
-	 * 
-	 * @param rawPkt the byte array received from the socket
-	 * @param packetSize the actual number of used bytes
-	 * @param adr the socket address from which the packet was received
-	 * @param rtpSession the RTPSession with the participant database
-	 */
-	protected CompRtcpPkt(byte[] rawPkt, int packetSize, InetSocketAddress adr, RTPSession rtpSession) {
-		if(RTPSession.rtcpDebugLevel > 7) {
-			System.out.println("-> CompRtcpPkt(" + rawPkt.getClass() + ", size " + packetSize + ", from " + adr.toString() + ", " + rtpSession.getClass() + ")");
-		}
-		//System.out.println("rawPkt.length:" + rawPkt.length + " packetSize:" + packetSize);
-		
-		// Chop it up
-		int start = 0;
-
-		while(start < packetSize && problem == 0) {
-			int length = (StaticProcs.bytesToUIntInt(rawPkt, start + 2)) + 1;
-			
-			if(length*4 + start > rawPkt.length) {
-				System.out.println("!!!! CompRtcpPkt.(rawPkt,..,..) length ("+ (length*4+start)
-						+ ") exceeds size of raw packet ("+rawPkt.length+") !");
-				this.problem = -3;
-			}
-			
-			int pktType = (int) rawPkt[start + 1];
-			
-			if(pktType < 0) {
-				pktType += 256;
-			}
-			
-			
-			if(start == 0) {
-				// Compound packets need to start with SR or RR
-				if(pktType != 200 && pktType != 201 ) {
-					if(RTPSession.rtcpDebugLevel > 3) {
-						System.out.println("!!!! CompRtcpPkt(rawPkt...) packet did not start with SR or RR");
-					}
-					this.problem = -1;
-				}
-				
-				// Padding bit should be zero for the first packet
-				if(((rawPkt[start] & 0x20) >>> 5) == 1) {
-					if(RTPSession.rtcpDebugLevel > 3) {
-						System.out.println("!!!! CompRtcpPkt(rawPkt...) first packet was padded");
-					}
-					this.problem = -2;
-				}
-			}
-			
-			//System.out.println("start: " + start + "   pktType: " + pktType + "  length:" + length );			
-			if(pktType == 200) {
-				addPacket(new RtcpPktSR(rawPkt,start,length*4));
-			} else if(pktType == 201 ) {
-				addPacket(new RtcpPktRR(rawPkt,start, -1));
-			} else if(pktType == 202) {
-				addPacket(new RtcpPktSDES(rawPkt,start, adr, rtpSession.partDb));
-			} else if(pktType == 203 ) {
-				addPacket(new RtcpPktBYE(rawPkt,start));
-			} else if(pktType == 204) {
-				addPacket(new RtcpPktAPP(rawPkt,start));
-			} else if(pktType == 205) {
-				addPacket(new RtcpPktRTPFB(rawPkt,start, rtpSession));
-			} else if(pktType == 206) {
-				addPacket(new RtcpPktPSFB(rawPkt,start,rtpSession));
-			} else {
-				System.out.println("!!!! CompRtcpPkt(byte[] rawPkt, int packetSize...) "
-						+"UNKNOWN RTCP PACKET TYPE:" + pktType);
-			}
-			
-			//System.out.println(" start:" + start + "  pktType:" + pktType + " length:" + length);
-			
-			start += length*4;
-			
-			if(RTPSession.rtcpDebugLevel > 12) {
-				System.out.println(" start:"+start+"  parsing pktType "+pktType+" length: "+length);
-			}
-		}
-		if(RTPSession.rtcpDebugLevel > 7) {
-			System.out.println("<- CompRtcpPkt(rawPkt....)");
-		}
-	}
-	
-	/**
-	 * Encode combines the RTCP packets in this.rtcpPkts into a byte[]
-	 * by calling the encode() function on each of them individually.
-	 * 
-	 * The order of rtcpPkts is preserved, so a RR or SR packet must be first.
-	 * 
-	 * @return the trimmed byte[] representation of the packet, ready to go into a UDP packet.
-	 */
-	protected byte[] encode() {
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println(" <- CompRtcpPkt.encode()");
-		}
-		
-		ListIterator<RtcpPkt>  iter = rtcpPkts.listIterator();
-
-		byte[] rawPkt = new byte[1500];
-		int index = 0;
-		
-		while(iter.hasNext()) {
-			RtcpPkt aPkt = (RtcpPkt) iter.next();
-			
-			if(aPkt.packetType == 200) {
-				RtcpPktSR pkt = (RtcpPktSR) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 201 ) {
-				RtcpPktRR pkt = (RtcpPktRR) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 202) {
-				RtcpPktSDES pkt = (RtcpPktSDES) aPkt;
-				pkt.encode();
-				//System.out.println(" ENCODE SIZE: " + pkt.rawPkt.length);
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 203) {
-				RtcpPktBYE pkt = (RtcpPktBYE) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 204) {
-				RtcpPktAPP pkt = (RtcpPktAPP) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 205) {
-				RtcpPktRTPFB pkt = (RtcpPktRTPFB) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else if(aPkt.packetType == 206) {
-				RtcpPktPSFB pkt = (RtcpPktPSFB) aPkt;
-				pkt.encode();
-				System.arraycopy(pkt.rawPkt, 0, rawPkt, index, pkt.rawPkt.length);
-				index += pkt.rawPkt.length;
-			} else {
-				System.out.println("CompRtcpPkt aPkt.packetType:" + aPkt.packetType);
-			}
-			//System.out.println(" packetType:" + aPkt.packetType + " length:" + aPkt.rawPkt.length + " index:" + index);
-		} 
-		
-		byte[] output = new byte[index];
-		
-		System.arraycopy(rawPkt, 0, output, 0, index);
-
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println(" -> CompRtcpPkt.encode()");
-		}
-		return output;
-	}
-}
\ No newline at end of file
--- a/src/jlibrtp/DataFrame.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-
-/**
- * Data structure to hold a complete frame if frame reconstruction
- * is enabled, or the data from an individual packet if it is not
- * 
- * It also contains most of the data from the individual packets 
- * that it is based on.
- * 
- * @author Arne Kepp
- */
-public class DataFrame {
-	/** The share RTP timestamp */
-	private long rtpTimestamp;
-	/** The calculated UNIX timestamp, guessed after 2 Sender Reports */
-	private long timestamp = -1;
-	/** the SSRC from which this frame originated */
-	private long SSRC;
-	/** contributing CSRCs, only read from the first packet */
-	private long[] CSRCs;
-	/** RTP payload type */
-	private int payloadType;
-	/** The marks on individual packets, ordered */
-	private boolean[] marks;
-	/** Whether any packets were marked or not */
-	private boolean anyMarked = false;
-	/** Whether the frame contains the expected number of packets */
-	private int isComplete = 0;
-	//private int dataLength;
-	/** The data from the individual packets, ordered */
-	private byte[][] data;
-	/** The sequence numbers of the individual packets, ordered */
-	private int[] seqNum;
-	/** The total amount of data bytes in this frame */
-	private int totalLength = 0;
-	/** The last sequence number in this frame */
-	protected int lastSeqNum;
-	/** The first sequence number in this frame */
-	protected int firstSeqNum;
-	/** The number of packets expected for a complete frame */
-	protected int noPkts;
-	
-	/**
-	 * The usual way to construct a frame is by giving it a PktBufNode,
-	 * which contains links to all the other pkts that make it up.
-	 */
-	protected DataFrame(PktBufNode aBufNode, Participant p, int noPkts) {
-		if(RTPSession.rtpDebugLevel > 6) {
-			System.out.println("-> DataFrame(PktBufNode, noPkts = " + noPkts +")");
-		}
-		this.noPkts = noPkts;
-		RtpPkt aPkt = aBufNode.pkt;
-		int pktCount = aBufNode.pktCount;
-		firstSeqNum = aBufNode.pktCount;
-		
-		// All this data should be shared, so we just get it from the first one
-		this.rtpTimestamp = aBufNode.timeStamp;
-		SSRC = aPkt.getSsrc();
-		CSRCs = aPkt.getCsrcArray();
-		
-		// Check whether we can compute an NTPish timestamp? Requires two SR reports 
-		if(p.ntpGradient > 0) {
-			//System.out.print(Long.toString(p.ntpOffset)+" " 
-			timestamp =  p.ntpOffset + (long) (p.ntpGradient*(double)(this.rtpTimestamp-p.lastSRRtpTs));
-		}
-		
-		// Make data the right length
-		int payloadLength = aPkt.getPayloadLength();
-		//System.out.println("aBufNode.pktCount " + aBufNode.pktCount);
-		data = new byte[aBufNode.pktCount][payloadLength];
-		seqNum = new int[aBufNode.pktCount];
-		marks = new boolean[aBufNode.pktCount];
-		
-		// Concatenate the data of the packets
-		int i;
-		for(i=0; i< pktCount; i++) {
-			aPkt = aBufNode.pkt;
-			byte[] temp = aPkt.getPayload();
-			totalLength += temp.length;
-			if(temp.length == payloadLength) {
-				data[i] = temp;
-			} else if(temp.length < payloadLength){
-				System.arraycopy(temp, 0, data[i], 0, temp.length);
-			} else {
-				System.out.println("DataFrame() received node structure with increasing packet payload size.");
-			}
-			//System.out.println("i " + i + " seqNum[i] " + seqNum[i] + " aBufNode"  + aBufNode);
-			seqNum[i] = aBufNode.seqNum;
-			marks[i] = aBufNode.pkt.isMarked();
-			if(marks[i])
-				anyMarked = true;
-			
-			// Get next node
-			aBufNode = aBufNode.nextFrameNode;
-		}
-		
-		lastSeqNum = seqNum[i - 1];
-		
-		if(noPkts > 0) {
-			int seqDiff = firstSeqNum - lastSeqNum;
-			if(seqDiff < 0)
-				seqDiff = (Integer.MAX_VALUE - firstSeqNum)  + lastSeqNum;
-			if(seqDiff == pktCount && pktCount == noPkts)
-				isComplete = 1;
-		} else {
-			isComplete = -1;
-		}
-		
-		if(RTPSession.rtpDebugLevel > 6) {
-			System.out.println("<- DataFrame(PktBufNode, noPkt), data length: " + data.length);
-		}
-	}
-	
-	/**
-	 * Returns a two dimensial array where the first dimension represents individual
-	 * packets, from which the frame is made up, in order of increasing sequence number. 
-	 * These indeces can be matched to the sequence numbers returned by sequenceNumbers().
-	 * 
-	 * @return 2-dim array with raw data from packets
-	 */
-	public byte[][] getData() {
-		return this.data;
-	}
-	
-	/**
-	 * Returns a concatenated version of the data from getData()
-	 * It ignores missing sequence numbers, but then isComplete()
-	 * will return false provided that RTPAppIntf.frameSize()
-	 * provides a non-negative number for this payload type.
-	 * 
-	 * @return byte[] with all the data concatenated
-	 */
-	public byte[] getConcatenatedData() {
-		if(this.noPkts < 2) {
-			byte[] ret = new byte[this.totalLength];
-			int pos = 0;
-		
-			for(int i=0; i<data.length; i++) {
-				int length = data[i].length;
-				
-				// Last packet may be shorter
-				if(pos + length > totalLength) 
-					length = totalLength - pos;
-				
-				System.arraycopy(data[i], 0, ret, pos, length);
-				pos += data[i].length;
-			}
-			return ret;
-		} else {
-			return data[0];
-		}
-	}
-	
-	/**
-	 * If two SR packet have been received jlibrtp will attempt to calculate 
-	 * the local UNIX timestamp (in milliseconds) of all packets received.
-	 * 
-	 * This value should ideally correspond to the local time when the 
-	 * SSRC sent the packet. Note that the source may not be reliable.
-	 * 
-	 * Returns -1 if less than two SRs have been received
-	 * 
-	 * @return the UNIX timestamp, similar to System.currentTimeMillis() or -1;
-	 */
-	public long timestamp() {
-		return this.timestamp;
-		
-	}
-	
-	/**
-	 * Returns the RTP timestamp of all the packets in the frame.
-	 * 
-	 * @return unmodified RTP timestamp
-	 */
-	public long rtpTimestamp() {
-		return this.rtpTimestamp;
-	}
-	
-	/**
-	 * Returns the payload type of the packets
-	 * 
-	 * @return the payload type of the packets
-	 */
-	public int payloadType() {
-		return this.payloadType;
-	}
-
-	/**
-	 * Returns an array whose values, for the same index, correpond to the 
-	 * sequence number of the packet from which the data came.
-	 * 
-	 * This information can be valuable in conjunction with getData(), 
-	 * to identify what parts of a frame are missing.
-	 * 
-	 * @return array with sequence numbers
-	 */
-	public int[] sequenceNumbers() {
-		return seqNum;
-	}
-	
-	/**
-	 * Returns an array whose values, for the same index, correpond to 
-	 * whether the data was marked or not. 
-	 * 
-	 * This information can be valuable in conjunction with getData().
-	 * 
-	 * @return array of booleans
-	 */
-	public boolean[] marks() {
-		return this.marks;
-	}
-	
-	/**
-	 * Returns true if any packet in the frame was marked.
-	 * 
-	 * This function should be used if all your frames fit
-	 * into single packets.
-	 * 
-	 * @return true if any packet was marked, false otherwise
-	 */
-	public boolean marked() {
-		return this.anyMarked;
-	}
-	
-	/**
-	 * The SSRC associated with this frame.
-	 * 
-	 * @return the ssrc that created this frame
-	 */
-	public long ssrc() {
-		return this.SSRC;
-	}
-	
-	/**
-	 * The SSRCs that contributed to this frame
-	 * 
-	 * @return an array of contributing SSRCs, or null
-	 */
-	public long[] csrcs() {
-		return this.CSRCs;
-	}
-	
-	/**
-	 * Checks whether the difference in sequence numbers corresponds
-	 * to the number of packets received for the current timestamp,
-	 * and whether this value corresponds to the expected number of
-	 * packets.
-	 * 
-	 * @return true if the right number of packets make up the frame
-	 */
-	public int complete() {
-		return this.isComplete;
-	}
-}
--- a/src/jlibrtp/DebugAppIntf.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-import java.net.InetSocketAddress;
-
-/**
- * DebugAppIntf can be registered on RTPSession to provide simple
- * debugging functionality. This is particularly useful to determine
- * whether the client is receing any data at all.
- * 
- * @author Arne Kepp
- *
- */
-
-public interface DebugAppIntf {
-	/**
-	 * This function wil notify you of any packets received, valid or not.
-	 * Useful for network debugging, and finding bugs in jlibrtp.
-	 * 
-	 * Type is an integer describing the type of event
-	 * -2 - Invalid RTCP packet received
-	 * -1 - Invalid RTP packet received
-	 * 0 - RTP packet received
-	 * 1 - RTCP packet received
-	 * 
-	 * Description is a string that should be meaningful to advanced users, such as
-	 * "RTP packet received from 127.0.0.1:12312, SSRC: 1380912 , payload type 1, packet size 16 octets"
-	 * or
-	 * "Invalid RTP packet received from 127.0.0.1:12312" 
-	 *
-	 * This function is synchonous and should return quickly.
-	 *
-	 * @param type , the type of event, see above.
-	 * @param socket , taken directly from the UDP packet
-	 * @param description , see above. 
-	 */
-	public void packetReceived(int type, InetSocketAddress socket, String description);
-	
-	/**
-	 * This function will notify you of any packets sent from this instance of RTPSession.
-	 * Useful for network debugging, and finding bugs in jlibrtp.
-	 * 
-	 * Type is an integer describing the type of event
-	 * 0 - RTP unicast packet sent
-	 * 1 - RTP multicast packet sent
-	 * 2 - RTCP unicast packet sent
-	 * 3 - RTCP multicast packet sent 
-	 * 
-	 * Description is a string that should be meaningful to advanced users, such as
-	 * 
-	 * This function is synchonous and should return quickly.
-	 * 
-	 * @param type , the type of event, see above
-	 * @param socket , taken directly from the UDP packet
-	 * @param description , see above
-	 */
-	public void packetSent(int type, InetSocketAddress socket, String description);
-	
-	/**
-	 * Other important events that can occur in session
-	 * -1 SSRC conflict
-	 *  0 Session is terminating
-	 * @param type see above
-	 * @param description , see above
-	 */
-	public void importantEvent(int type, String description);
-}
--- a/src/jlibrtp/LICENSE.txt	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,490 +0,0 @@
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-    
-
--- a/src/jlibrtp/Participant.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,437 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.InetSocketAddress;
-
-/**
- * A participant represents a peer in an RTPSession. Based on the information stored on 
- * these objects, packets are processed and statistics generated for RTCP.
- */
-public class Participant {
-	/** Whether the participant is unexpected, e.g. arrived through unicast with SDES */
-	protected boolean unexpected = false;
-	/** Where to send RTP packets (unicast)*/
-	protected InetSocketAddress rtpAddress = null; 
-	/** Where to send RTCP packets (unicast) */
-	protected InetSocketAddress rtcpAddress = null;
-	/** Where the first RTP packet was received from */
-	protected InetSocketAddress rtpReceivedFromAddress = null;
-	/** Where the first RTCP packet was received from */
-	protected InetSocketAddress rtcpReceivedFromAddress = null;
-	
-	/** SSRC of participant */
-	protected long ssrc = -1;
-	/** SDES CNAME */
-	protected String cname = null;
-	/** SDES The participant's real name */
-	protected String name = null;
-	/** SDES The participant's email */
-	protected String email = null;
-	/** SDES The participant's phone number */
-	protected String phone = null;
-	/** SDES The participant's location*/
-	protected String loc = null;
-	/** SDES The tool the participants is using */
-	protected String tool = null;
-	/** SDES A note */
-	protected String note = null;
-	/** SDES A priv string, loosely defined */
-	protected String priv = null;
-
-	// Receiver Report Items
-	/** RR First sequence number */
-	protected int firstSeqNumber = -1;
-	/** RR Last sequence number */
-	protected int lastSeqNumber = 0;
-	/** RR Number of times sequence number has rolled over */
-	protected long seqRollOverCount = 0;
-	/** RR Number of packets received */
-	protected long receivedPkts = 0;
-	/** RR Number of octets received */
-	protected long receivedOctets = 0;
-	/** RR Number of packets received since last SR */
-	protected int receivedSinceLastSR = 0;
-	/** RR Sequence number associated with last SR */
-	protected int lastSRRseqNumber = 0;
-	/** RR Interarrival jitter */
-	protected double interArrivalJitter = -1.0;
-	/** RR Last received RTP Timestamp */
-	protected long lastRtpTimestamp = 0;
-	
-	/** RR Middle 32 bits of the NTP timestamp in the last SR */
-	protected long timeStampLSR = 0;
-	/** RR The time when we actually got the last SR */
-	protected long timeReceivedLSR = 0;
-	
-	/** Gradient where UNIX timestamp = ntpGradient*RTPTimestamp * ntpOffset */
-	protected double ntpGradient = -1;
-	/** Offset where UNIX timestamp = ntpGradient*RTPTimestamp * ntpOffset */
-	protected long ntpOffset = -1;
-	/** Last NTP received in SR packet, MSB */
-	protected long lastNtpTs1 = 0; //32 bits
-	/** Last NTP received in SR packet, LSB */
-	protected long lastNtpTs2 = 0; //32 bits
-	/** RTP Timestamp in last SR packet */
-	protected long lastSRRtpTs = 0; //32 bits
-	
-	/** UNIX time when a BYE was received from this participant, for pruning */
-	protected long timestampBYE = -1;	// The user said BYE at this time
-	
-	/** Store the packets received from this participant */
-	protected PktBuffer pktBuffer = null;
-
-	/** UNIX time of last RTP packet, to check whether this participant has sent anything recently */
-	protected long lastRtpPkt = -1; //Time of last RTP packet
-	/** UNIX time of last RTCP packet, to check whether this participant has sent anything recently */
-	protected long lastRtcpPkt = -1; //Time of last RTCP packet
-	/** UNIX time this participant was added by application, to check whether we ever heard back */
-	protected long addedByApp = -1; //Time the participant was added by application
-	/** UNIX time of last time we sent an RR to this user */
-	protected long lastRtcpRRPkt = -1; //Timestamp of last time we sent this person an RR packet
-	/** Unix time of second to last time we sent and RR to this user */
-	protected long secondLastRtcpRRPkt = -1; //Timestamp of 2nd to last time we sent this person an RR Packet
-		
-	/**
-	 * Create a basic participant. If this is a <b>unicast</b> session you must provide network address (ipv4 or ipv6) and ports for RTP and RTCP, 
-	 * as well as a cname for this contact. These things should be negotiated through SIP or a similar protocol.
-	 * 
-	 * jlibrtp will listen for RTCP packets to obtain a matching SSRC for this participant, based on cname.
-	 * @param networkAddress string representation of network address (ipv4 or ipv6). Use "127.0.0.1" for multicast session.
-	 * @param rtpPort port on which peer expects RTP packets. Use 0 if this is a sender-only, or this is a multicast session.
-	 * @param rtcpPort port on which peer expects RTCP packets. Use 0 if this is a sender-only, or this is a multicast session.
-	 */
-	public Participant(String networkAddress, int rtpPort, int rtcpPort) {
-		if(RTPSession.rtpDebugLevel > 6) {
-			System.out.println("Creating new participant: " + networkAddress);
-		}
-		
-		// RTP
-		if(rtpPort > 0) {
-			try {
-				rtpAddress = new InetSocketAddress(networkAddress, rtpPort);
-			} catch (Exception e) {
-				System.out.println("Couldn't resolve " + networkAddress);
-			}
-			//isReceiver = true;
-		}
-		
-		// RTCP 
-		if(rtcpPort > 0) {
-			try {
-				rtcpAddress = new InetSocketAddress(networkAddress, rtcpPort);
-			} catch (Exception e) {
-				System.out.println("Couldn't resolve " + networkAddress);
-			}
-		}
-		
-		//By default this is a sender
-		//isSender = true;
-	}
-	
-	// We got a packet, but we don't know this person yet.
-	protected Participant(InetSocketAddress rtpAdr, InetSocketAddress rtcpAdr, long SSRC) {
-		rtpReceivedFromAddress = rtpAdr;
-		rtcpReceivedFromAddress = rtcpAdr;
-		ssrc = SSRC;
-		unexpected = true;
-	}
-	
-	// Dummy constructor to ease testing
-	protected Participant() {
-		System.out.println("Don't use the Participan(void) Constructor!");
-	}
-	
-	/**
-	 * RTP Address registered with this participant.
-	 * 
-	 * @return address of participant
-	 */
-	InetSocketAddress getRtpSocketAddress() {
-		return rtpAddress;
-	}
-	
-	
-	/**
-	 * RTCP Address registered with this participant.
-	 * 
-	 * @return address of participant
-	 */
-	InetSocketAddress getRtcpSocketAddress() {
-		return rtcpAddress;
-	}
-
-	/**
-	 * InetSocketAddress this participant has used to
-	 * send us RTP packets.
-	 * 
-	 * @return address of participant
-	 */
-	InetSocketAddress getRtpReceivedFromAddress() {
-		return rtpAddress;
-	}
-
-	
-	
-	/**
-	 * InetSocketAddress this participant has used to
-	 * send us RTCP packets.
-	 * 
-	 * @return address of participant
-	 */
-	InetSocketAddress getRtcpReceivedFromAddress() {
-		return rtcpAddress;
-	}
-	
-	
-	/**
-	 * CNAME registered for this participant.
-	 * 
-	 * @return the cname
-	 */
-	public String getCNAME() {
-		return cname;
-	}
-	
-	
-	/**
-	 * NAME registered for this participant.
-	 * 
-	 * @return the name
-	 */
-	public String getNAME() {
-		return name;
-	}
-	
-	/**
-	 * EMAIL registered for this participant.
-	 * 
-	 * @return the email address
-	 */
-	public String getEmail() {
-		return email;
-	}
-	
-	/**
-	 * PHONE registered for this participant.
-	 * 
-	 * @return the phone number
-	 */
-	public String getPhone() {
-		return phone;
-	}
-	
-	/**
-	 * LOCATION registered for this participant.
-	 * 
-	 * @return the location
-	 */
-	public String getLocation() {
-		return loc;
-	}
-	
-	/**
-	 * NOTE registered for this participant.
-	 * 
-	 * @return the note
-	 */
-	public String getNote() {
-		return note;
-	}
-	
-	/**
-	 * PRIVATE something registered for this participant.
-	 * 
-	 * @return the private-string
-	 */
-	public String getPriv() {
-		return priv;
-	}
-	
-	/**
-	 * TOOL something registered for this participant.
-	 * 
-	 * @return the tool
-	 */
-	public String getTool() {
-		return tool;
-	}
-		
-	/**
-	 * SSRC for participant, determined through RTCP SDES
-	 * 
-	 * @return SSRC (32 bit unsigned integer as long)
-	 */
-	public long getSSRC() {
-		return this.ssrc;
-	}
-	
-	/** 
-	 * Updates the participant with information for receiver reports.
-	 * 
-	 * @param packetLength to keep track of received octets
-	 * @param pkt the most recently received packet
-	 */
-	protected void updateRRStats(int packetLength, RtpPkt pkt) {
-		int curSeqNum = pkt.getSeqNumber();
-		
-		if(firstSeqNumber < 0) {
-			firstSeqNumber = curSeqNum;
-		}
-		
-		receivedOctets += packetLength;
-		receivedSinceLastSR++;
-		receivedPkts++;
-		
-		long curTime =  System.currentTimeMillis();
-		
-		if( this.lastSeqNumber < curSeqNum ) {
-			//In-line packet, best thing you could hope for
-			this.lastSeqNumber = curSeqNum;
-						
-		} else if(this.lastSeqNumber - this.lastSeqNumber < -100) {
-			//Sequence counter rolled over
-			this.lastSeqNumber = curSeqNum;
-			seqRollOverCount++;
-			
-		} else {
-			//This was probably a duplicate or a late arrival.
-		}
-		
-		// Calculate jitter
-		if(this.lastRtpPkt > 0) {
-			
-			long D = (pkt.getTimeStamp() - curTime) - (this.lastRtpTimestamp - this.lastRtpPkt);
-			if(D < 0)
-				D = (-1)*D;
-			
-			this.interArrivalJitter += ((double)D - this.interArrivalJitter) / 16.0;
-		}
-
-		lastRtpPkt = curTime;
-		lastRtpTimestamp = pkt.getTimeStamp();
-	}
-	
-	/**
-	 * Calculates the extended highest sequence received by adding 
-	 * the last sequence number to 65536 times the number of times 
-	 * the sequence counter has rolled over.
-	 * 
-	 * @return extended highest sequence
-	 */
-	protected long getExtHighSeqRecv() {
-		return (65536*seqRollOverCount + lastSeqNumber);
-	}
-	
-	/**
-	 * Get the fraction of lost packets, calculated as described
-	 * in RFC 3550 as a fraction of 256.
-	 * 
-	 * @return the fraction of lost packets since last SR received
-	 */
-	protected int getFractionLost() {
-		int expected = (lastSeqNumber - lastSRRseqNumber);
-		if(expected < 0)
-			expected = 65536 + expected;
-                
-		int fraction = 256 * (expected - receivedSinceLastSR);
-		if(expected > 0) {
-			fraction = (fraction / expected);
-		} else {
-			fraction = 0;
-		}
-		
-		//Clear counters 
-		receivedSinceLastSR = 0;
-		lastSRRseqNumber = lastSeqNumber;
-		
-		return fraction;
-	}
-	
-	/**
-	 * The total number of packets lost during the session.
-	 * 
-	 * Returns zero if loss is negative, i.e. duplicates have been received.
-	 * 
-	 * @return number of lost packets, or zero.
-	 */
-	protected long getLostPktCount() {
-		long lost = (this.getExtHighSeqRecv() - this.firstSeqNumber) - receivedPkts;
-		
-		if(lost < 0)
-			lost = 0;
-		return lost;
-	}
-	
-	/** 
-	 * 
-	 * @return the interArrivalJitter, calculated continuously
-	 */
-	protected double getInterArrivalJitter() {
-		return this.interArrivalJitter;
-	}
-	
-	/**
-	 * Set the timestamp for last sender report
-	 * 
-	 * @param ntp1 high order bits
-	 * @param ntp2 low order bits
-	 */
-	protected void setTimeStampLSR(long ntp1, long ntp2) {
-		// Use what we've got
-		byte[] high = StaticProcs.uIntLongToByteWord(ntp1);
-		byte[] low = StaticProcs.uIntLongToByteWord(ntp2);
-		low[3] = low[1];
-		low[2] = low[0];
-		low[1] = high[3];
-		low[0] = high[2];
-		
-		this.timeStampLSR = StaticProcs.bytesToUIntLong(low, 0);
-	}
-	
-	/**
-	 * Calculate the delay between the last received sender report
-	 * and now.
-	 * 
-	 * @return the delay in units of 1/65.536ms
-	 */
-	protected long delaySinceLastSR() {
-		if(this.timeReceivedLSR < 1) 
-			return 0;
-			
-		long delay = System.currentTimeMillis() - this.timeReceivedLSR;
-		
-		//Convert ms into 1/65536s = 1/65.536ms
-		return (long) ((double)delay * 65.536);
-	}
-	
-	/**
-	 * Only for debugging purposes
-	 */
-	public void debugPrint() {
-		System.out.print(" Participant.debugPrint() SSRC:"+this.ssrc+" CNAME:"+this.cname);
-		if(this.rtpAddress != null)
-			System.out.print(" RTP:"+this.rtpAddress.toString());
-		if(this.rtcpAddress != null)
-			System.out.print(" RTCP:"+this.rtcpAddress.toString());
-		System.out.println("");
-		
-		System.out.println("                          Packets received:"+this.receivedPkts);
-	}
-}
--- a/src/jlibrtp/ParticipantDatabase.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-/**
- * The participant database maintains three hashtables with participants.
- * 
- * The key issue is to be fast for operations that happen every time an
- * RTP packet is sent or received. We allow linear searching in cases 
- * where we need to update participants with information.
- * 
- * The keying is therefore usually the SSRC. In cases where we have the
- * cname, but no SSRC is known (no SDES packet has been received), a
- * simple hash i calculated based on the CNAME. The RTCP code should,
- * when receiving SDES packets, check whether the participant is known
- * and update the copy in this database with SSRC if needed.
- * 
- * @author Arne Kepp
- */
-public class ParticipantDatabase {
-	/** The parent RTP Session */
-	RTPSession rtpSession = null;
-	/** 
-	 * A linked list to hold participants explicitly added by the application
-	 * In unicast mode this is the list used for RTP and RTCP transmission, 
-	 * in multicast it should not be in use. 
-	 */
-	LinkedList<Participant> receivers = new LinkedList<Participant>();	
-	/** 
-	 * The hashtable holds participants added through received RTP and RTCP packets,
-	 * as well as participants that have been linked to an SSRC by ip address (in unicast mode).
-	 */
-	ConcurrentHashMap<Long,Participant> ssrcTable = new ConcurrentHashMap<Long,Participant>();
-	
-	/**
-	 * Simple constructor
-	 * 
-	 * @param parent parent RTPSession
-	 */
-	protected ParticipantDatabase(RTPSession parent) {
-		rtpSession = parent;
-	}
-	
-	/**
-	 * 
-	 * @param cameFrom 0: Application, 1: RTP packet, 2: RTCP
-	 * @param p the participant
-	 * @return 0 if okay, -1 if not 
-	 */
-	protected int addParticipant(int cameFrom, Participant p) {
-		//Multicast or not?
-		if(this.rtpSession.mcSession) {
-			return this.addParticipantMulticast(cameFrom, p);
-		} else {
-			return this.addParticipantUnicast(cameFrom, p);
-		}
-		
-	}
-	
-	/**
-	 * Add a multicast participant to the database
-	 * 
-	 * @param cameFrom 0: Application, 1,2: discovered through RTP or RTCP
-	 * @param p the participant to add
-	 * @return 0 if okay, -2 if redundant, -1 if adding participant to multicast
-	 */
-	private int addParticipantMulticast(int cameFrom, Participant p) {
-		if( cameFrom == 0) {
-			System.out.println("ParticipantDatabase.addParticipant() doesnt expect" 
-					+ " application to add participants to multicast session.");
-			return -1;
-		} else {
-			// Check this one is not redundant
-			if(this.ssrcTable.contains(p.ssrc)) {
-				System.out.println("ParticipantDatabase.addParticipant() SSRC "
-						+"already known " + Long.toString(p.ssrc));
-				return -2;
-			} else {
-				this.ssrcTable.put(p.ssrc, p);
-				return 0;
-			}
-		}
-	}
-	
-	/**
-	 * Add a unicast participant to the database
-	 * 
-	 * Result will be reported back through tpSession.appIntf.userEvent
-	 * 
-	 * @param cameFrom 0: Application, 1,2: discovered through RTP or RTCP
-	 * @param p the participant to add
-	 * @return 0 if new, 1 if 
-	 */
-	private int addParticipantUnicast(int cameFrom, Participant p) {
-		if(cameFrom == 0) {
-			//Check whether there is a match in the ssrcTable
-			boolean notDone = true;
-			
-			Enumeration<Participant> enu = this.ssrcTable.elements();
-			while(notDone && enu.hasMoreElements()) {
-				Participant part = enu.nextElement();
-				if(part.unexpected && 
-						(part.rtcpReceivedFromAddress.equals(part.rtcpAddress.getAddress()) 
-						|| part.rtpReceivedFromAddress.equals(part.rtpAddress.getAddress()))) {
-					
-					part.rtpAddress = p.rtpAddress;
-					part.rtcpAddress = p.rtcpAddress;
-					part.unexpected = false;
-
-					//Report the match back to the application
-					Participant[] partArray = {part};
-					this.rtpSession.appIntf.userEvent(5, partArray);
-					
-					notDone = false;
-					p = part;
-				}
-			}
-
-			//Add to the table of people that we send packets to
-			this.receivers.add(p);
-			return 0;
-			
-		} else {
-			//Check whether there's a match in the receivers table
-			boolean notDone = true;
-			//System.out.println("GOT " + p.cname);
-			Iterator<Participant> iter = this.receivers.iterator();
-			
-			while(notDone && iter.hasNext()) {
-				Participant part = iter.next();
-				
-				//System.out.println(part.rtpAddress.getAddress().toString()
-				//		+ " " + part.rtcpAddress.getAddress().toString() 
-				//		+ " " + p.rtpReceivedFromAddress.getAddress().toString()
-				//		+ " " + p.rtcpReceivedFromAddress.getAddress().toString());
-				
-				//System.out.println(" HUUHHHH?  " + p.rtcpReceivedFromAddress.getAddress().equals(part.rtcpAddress.getAddress()));
-				if((cameFrom == 1 && p.rtpReceivedFromAddress.getAddress().equals(part.rtpAddress.getAddress()))
-					|| (cameFrom == 2 && p.rtcpReceivedFromAddress.getAddress().equals(part.rtcpAddress.getAddress()))) {
-					
-					part.rtpReceivedFromAddress = p.rtpReceivedFromAddress;
-					part.rtcpReceivedFromAddress = p.rtcpReceivedFromAddress;
-					
-					// Move information
-					part.ssrc = p.ssrc;
-					part.cname = p.cname;
-					part.name = p.name;
-					part.loc = p.loc;
-					part.phone = p.phone;
-					part.email = p.email;
-					part.note = p.note;
-					part.tool = p.tool;
-					part.priv = p.priv;
-					
-					this.ssrcTable.put(part.ssrc, part);
-					
-					//Report the match back to the application
-					Participant[] partArray = {part};
-					this.rtpSession.appIntf.userEvent(5, partArray);
-					return 0;
-				}
-			}
-			
-			// No match? ok
-			this.ssrcTable.put(p.ssrc, p);				
-			return 0;
-		}
-	}
-	
-	/**
-	 * Remove a participant from all tables
-	 * 
-	 * @param p the participant to be removed
-	 */
-	protected void removeParticipant(Participant p) {
-		if(! this.rtpSession.mcSession)
-			this.receivers.remove(p);
-		
-		this.ssrcTable.remove(p.ssrc, p);
-	}
-		
-	/**
-	 * Find a participant based on the ssrc
-	 * 
-	 * @param ssrc of the participant to be found
-	 * @return the participant, null if unknonw
-	 */
-	protected Participant getParticipant(long ssrc) {
-		Participant p = null;
-		p = ssrcTable.get(ssrc);
-		return p; 
-	}
-	
-	/**
-	 * Iterator for all the unicast receivers.
-	 * 
-	 * This one is used by both RTP for sending packets, as well as RTCP.
-	 * 
-	 * @return iterator for unicast participants
-	 */
-	protected Iterator<Participant> getUnicastReceivers() {
-		if(! this.rtpSession.mcSession) {
-			return this.receivers.iterator();
-		} else {
-			System.out.println("Request for ParticipantDatabase.getUnicastReceivers in multicast session");
-			return null;
-		}
-	}
-	
-	/**
-	 * Enumeration of all the participants with known ssrcs.
-	 * 
-	 * This is primarily used for sending packets in multicast sessions.
-	 * 
-	 * @return enumerator with all the participants with known SSRCs
-	 */
-	protected Enumeration<Participant> getParticipants() {
-		return this.ssrcTable.elements();
-	}
-	
-	protected void debugPrint() {
-		System.out.println("   ParticipantDatabase.debugPrint()");
-		Participant p;
-		Enumeration enu = ssrcTable.elements();
-		while(enu.hasMoreElements()) {
-			p = (Participant) enu.nextElement();
-			System.out.println("           ssrcTable ssrc:"+p.ssrc+" cname:"+p.cname
-					+" loc:"+p.loc+" rtpAddress:"+p.rtpAddress+" rtcpAddress:"+p.rtcpAddress);
-		}
-		
-		Iterator<Participant> iter = receivers.iterator();
-		while(iter.hasNext()) {
-			p = iter.next();
-			System.out.println("           receivers: "+p.rtpAddress.toString());
-		}
-	}
-}
--- a/src/jlibrtp/PktBufNode.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * This is a four-directional data structures used for
- * the frame buffer, i.e. buffer for pkts that need
- * to be assimilated into complete frames.
- * 
- * All the actual work is done by PktBuffer.
- * 
- * @author Arne Kepp
- *
- */
-public class PktBufNode {
-	/** The next node (RTP Timestamp), looking from the back -> next means older */
-	protected PktBufNode nextFrameQueueNode = null;
-	/** The previous node (RTP Timestmap), looking from the back -> prev means newer */
-	protected PktBufNode prevFrameQueueNode = null;
-	/** The next node within the frame, i.e. higher sequence number, same RTP timestamp */
-	protected PktBufNode nextFrameNode = null;
-	/** Number of packets with the same RTP timestamp */
-	protected int pktCount;
-	/** The RTP timeStamp associated with this node */
-	protected long timeStamp;
-	/** The sequence number associated with this node */
-	protected int seqNum;
-	/** The payload, a parsed RTP Packet */
-	protected RtpPkt pkt = null;
-	
-	/**
-	 * Create a new packet buffer node based on a packet
-	 * @param aPkt the packet
-	 */
-	protected PktBufNode(RtpPkt aPkt) {
-		pkt = aPkt;
-		timeStamp = aPkt.getTimeStamp();
-		seqNum = aPkt.getSeqNumber();
-		pktCount = 1;
-	}
-}
--- a/src/jlibrtp/PktBuffer.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,473 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * A PktBuffer stores packets either for buffering purposes,
- * or because they need to be assimilated to create a complete frame.
- * 
- * This behavior can be controlled through rtpSession.pktBufBehavior()
- * 
- * It optionally drops duplicate packets.
- * 
- * Note that newest is the most recently received, i.e. highest timeStamp
- * Next means new to old (from recently received to previously received) 
- * 
- * @author Arne Kepp
- */
-public class PktBuffer {
-	/** The RTPSession holds information common to all packetBuffers, such as max size */
-	RTPSession rtpSession;
-	/** SSRC of the the participant that this buffer is for */
-	long SSRC;
-	/** The parent participant */
-	Participant p;
-	/** The length of the buffer */
-	int length = 0;
-	/** The oldest, least recently received, packet */
-	PktBufNode oldest = null;
-	/** The newest, most recently received, packet */
-	PktBufNode newest = null;
-	
-	/** The last sequence number received */
-	int lastSeqNumber = -1;
-	/** The last timestamp */
-	long lastTimestamp = -1;
-
-	/** 
-	 * Creates a new PktBuffer, a linked list of PktBufNode
-	 * 
-	 * @param rtpSession the parent RTPSession
-	 * @param p the participant to which this packetbuffer belongs.
-	 * @param aPkt The first RTP packet, to be added to the buffer 
-	 */
-	protected PktBuffer(RTPSession rtpSession, Participant p, RtpPkt aPkt) {
-		this.rtpSession = rtpSession;
-		this.p = p;
-		SSRC = aPkt.getSsrc();
-		PktBufNode newNode = new PktBufNode(aPkt);
-		oldest = newNode;
-		newest = newNode;
-		//lastSeqNumber = (aPkt.getSeqNumber() - 1);
-		//lastTimestamp = aPkt.getTimeStamp();
-		length = 1;
-	}
-
-	/**
-	 * Adds a packet, this happens in constant time if they arrive in order.
-	 * Optimized for the case where each pkt is a complete frame.
-	 * 
-	 * @param aPkt the packet to be added to the buffer.
-	 * @return integer, negative if operation failed (see code)
-	 */
-	protected synchronized int addPkt(RtpPkt aPkt) {
-		if(aPkt == null) {
-			System.out.println("! PktBuffer.addPkt(aPkt) aPkt was null");
-			return -5;
-		}
-
-		long timeStamp = aPkt.getTimeStamp();
-		if(RTPSession.rtpDebugLevel > 7) {
-			System.out.println("-> PktBuffer.addPkt() , length:" + length + " , timeStamp of Pkt: " + Long.toString(timeStamp));
-		}
-
-		
-		PktBufNode newNode = new PktBufNode(aPkt);
-		if(aPkt.getSsrc() != SSRC) {
-			System.out.println("PktBuffer.addPkt() SSRCs don't match!");
-		}
-		
-		int retVal = 0;
-		if(this.rtpSession.pktBufBehavior > 0) {
-			retVal = bufferedAddPkt(newNode);
-		} else if(this.rtpSession.pktBufBehavior == 0) {
-			retVal = filteredAddPkt(newNode);
-		} else if(this.rtpSession.pktBufBehavior == -1) {
-			retVal = unfilteredAddPkt(newNode);
-		}
-		
-
-		if(RTPSession.rtpDebugLevel > 7) {
-			if(RTPSession.rtpDebugLevel > 10) {
-				this.debugPrint();
-			}
-			System.out.println("<- PktBuffer.addPkt() , length:" + length + " returning " + retVal);
-		}
-		return retVal;
-	}
-	
-	/**
-	 * Adds packets in the same order that they arrive,
-	 * doesn't do any filering or processing.
-	 * 
-	 * @param newNode the node to add to the packet buffer
-	 * @return 0 if everything is okay, -1 otherwise
-	 */
-	private int unfilteredAddPkt(PktBufNode newNode) {
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("<->    PktBuffer.unfilteredAddPkt()");
-		}
-		//No magic, just add to the end
-		if(oldest != null) {
-			oldest.nextFrameQueueNode = newNode;
-			newNode.prevFrameQueueNode = oldest; 
-			oldest = newNode;
-		} else {
-			oldest = newNode;
-			newest = newNode;
-		}
-		return 0;
-	}
-	
-	/**
-	 * Takes care of duplicate packets
-	 * 
-	 * @param newNode the node to add to the packet buffer
-	 * @return 0 if everything is okay, -1 otherwise
-	 */
-	private int filteredAddPkt(PktBufNode newNode) {
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("<->    PktBuffer.filteredAddPkt()");
-		}
-		
-		if(length == 0) {
-			// The buffer was empty, this packet is the one and only.
-			newest = newNode;
-			oldest = newNode;
-			length = 1;
-		} else {
-			// The packetbuffer is not empty.
-			if(newNode.timeStamp > newest.timeStamp || newNode.seqNum > newest.seqNum && (newNode.seqNum - newest.seqNum) < 10) {
-				// Packet came in order
-				newNode.nextFrameQueueNode = newest;
-				newest.prevFrameQueueNode = newNode;
-				newest = newNode;
-				length++;
-			} else {
-					if(RTPSession.rtpDebugLevel > 2) {
-						System.out.println("PktBuffer.filteredAddPkt Dropped a packet due to lag! " +  newNode.timeStamp + " " 
-								+ newNode.seqNum + " vs "+ oldest.timeStamp + " " + oldest.seqNum);
-					}
-					return -1;
-			}
-		}
-		
-		return 0;
-	}
-	
-	/**
-	 * Does most of the packet organization for the application.
-	 * Packets are put in order, duplicate packets or late arrivals are discarded
-	 * 
-	 * If multiple packets make up a frame, these will also be organized
-	 * by RTP timestamp and sequence number, and returned as a complete frame.
-	 * 
-	 * @param newNode the node to add to the packet buffer
-	 * @return 0 if everything is okay, -1 otherwise
-	 */
-	private int bufferedAddPkt(PktBufNode newNode) {
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("<->    PktBuffer.bufferedAddPkt()");
-		}
-		if(length == 0) {
-			// The buffer was empty, this packet is the one and only.
-			newest = newNode;
-			oldest = newNode;
-		} else {
-			// The packetbuffer is not empty.
-			if(newNode.timeStamp > newest.timeStamp || newNode.seqNum > newest.seqNum) {
-				// Packet came in order
-				newNode.nextFrameQueueNode = newest;
-				newest.prevFrameQueueNode = newNode;
-				newest = newNode;
-			} else {
-				//There are packets, we need to order this one right.
-				if(! pktOnTime(newNode.timeStamp, newNode.seqNum) && rtpSession.pktBufBehavior > -1) {
-					// We got this too late, can't put it in order anymore.
-					if(RTPSession.rtpDebugLevel > 2) {
-						System.out.println("PktBuffer.addPkt Dropped a packet due to lag! " +  newNode.timeStamp + " " 
-								+ newNode.seqNum + " vs "+ oldest.timeStamp + " " + oldest.seqNum);
-					}
-					return -1;
-				}
-
-				//Need to do some real work, find out where it belongs (linear search from the back).
-				PktBufNode tmpNode = newest;
-				while(tmpNode.timeStamp > newNode.timeStamp) {
-					tmpNode = tmpNode.nextFrameQueueNode;
-				}
-				
-				if( tmpNode.timeStamp == newNode.timeStamp
-						&& rtpSession.frameReconstruction
-						&& newNode.seqNum != tmpNode.seqNum) {
-					//Packet has same timestamp, presumably belongs to frame. Need to order within frame.
-					if(RTPSession.rtpDebugLevel > 8) {
-						System.out.println("Found pkt with existing timeStamp: " + newNode.timeStamp);
-					}
-					int ret = addToFrame(tmpNode, newNode);
-					if(ret != 0) {
-						return ret;
-					}
-				} else {
-								
-					// Check that it's not a duplicate
-					if(tmpNode.timeStamp == newNode.timeStamp && newNode.seqNum == tmpNode.seqNum) {
-						if(RTPSession.rtpDebugLevel > 2) {
-							System.out.println("PktBuffer.addPkt Dropped a duplicate packet! " 
-									+  newNode.timeStamp + " " + newNode.seqNum );
-						}
-						return -1;
-					}
-				
-					// Insert into buffer
-					newNode.nextFrameQueueNode = tmpNode;
-					newNode.prevFrameQueueNode = tmpNode.prevFrameQueueNode;
-
-					// Update the node behind
-					if(newNode.prevFrameQueueNode != null) {
-						newNode.prevFrameQueueNode.nextFrameQueueNode = newNode;
-					}
-					tmpNode.prevFrameQueueNode = newNode;
-
-					if(newNode.timeStamp > newest.timeStamp) {
-						newest = newNode; 
-					}
-				}
-			}
-		}
-		// Update the length of this buffer
-		length++;
-		return 0;
-	}
-	
-	/**
-	 * 
-	 * @param frameNode the node currently representing the frame in the packet buffer
-	 * @param newNode the new node to be added to the frame
-	 * @return 0 if no error, -2 if this is a duplicate packet
-	 */
-	private int addToFrame(PktBufNode frameNode, PktBufNode newNode) {
-		// Node has same timeStamp, assume pkt belongs to frame
-		
-		if(frameNode.seqNum < newNode.seqNum) {
-			// this is not the first packet in the frame
-			frameNode.pktCount++;
-			
-			// Find the right spot
-			while( frameNode.nextFrameNode != null 
-					&& frameNode.nextFrameNode.seqNum < newNode.seqNum) {
-				frameNode = frameNode.nextFrameNode;
-			}
-			
-			// Check whether packet is duplicate
-			if(frameNode.nextFrameNode != null 
-					&& frameNode.nextFrameNode.seqNum == newNode.seqNum) {
-				if(RTPSession.rtpDebugLevel > 2) {
-					System.out.println("PktBuffer.addPkt Dropped a duplicate packet!");
-				}
-				return -2;
-			}
-			
-			newNode.nextFrameNode = frameNode.nextFrameNode;
-			frameNode.nextFrameNode = newNode;
-		
-		} else {
-			// newNode has the lowest sequence number
-			newNode.nextFrameNode = frameNode;
-			newNode.pktCount = frameNode.pktCount + 1;
-			
-			//Update the queue
-			if(frameNode.nextFrameQueueNode != null) {
-				frameNode.nextFrameQueueNode.prevFrameQueueNode = newNode;
-				newNode.nextFrameQueueNode = frameNode.nextFrameQueueNode;
-				frameNode.nextFrameQueueNode = null;
-			}
-			if(frameNode.prevFrameQueueNode != null) {
-				frameNode.prevFrameQueueNode.nextFrameQueueNode = newNode;
-				newNode.prevFrameQueueNode = frameNode.prevFrameQueueNode;
-				frameNode.prevFrameQueueNode = null;
-			}
-			if(newest.timeStamp == newNode.timeStamp) {
-				newest = newNode;
-			}
-		}
-
-		return 0;
-	}
-
-	/** 
-	 * Checks the oldest frame, if there is one, sees whether it is complete.
-	 * @return Returns null if there are no complete frames available.
-	 */
-	protected synchronized DataFrame popOldestFrame() {
-		if(RTPSession.rtpDebugLevel > 7) {
-			System.out.println("-> PktBuffer.popOldestFrame()");
-		}
-		if(RTPSession.rtpDebugLevel > 10) {
-			this.debugPrint();
-		}
-		
-		if(this.rtpSession.pktBufBehavior > 0) {
-			return this.bufferedPopFrame();
-		} else {
-			return this.unbufferedPopFrame();
-		}
-	}
-	
-	/**
-	 * Will return the oldest frame without checking whether it is in
-	 * the right order, or whether we should wate for late arrivals.
-	 * 
-	 * @return the first frame on the queue, null otherwise
-	 */
-	private DataFrame unbufferedPopFrame() {
-		if(oldest != null) {
-			PktBufNode retNode = oldest;
-			
-			popFrameQueueCleanup(retNode, retNode.seqNum);
-			
-			return new DataFrame(retNode, this.p, 
-					rtpSession.appIntf.frameSize(retNode.pkt.getPayloadType()));
-		} else {
-			return null;
-		}
-	}
-	
-	/**
-	 * Only returns if the buffer is full, i.e. length exceeds
-	 * rtpSession.pktBufBehavior, or if the next packet directly
-	 * follows the previous one returned to the application.
-	 * 
-	 * @return first frame in order, null otherwise
-	 */
-	private DataFrame bufferedPopFrame() {
-		PktBufNode retNode = oldest;
-		/**
-		 * Three scenarios:
-		 * 1) There are no packets available
-		 * 2) The first packet is vailable and in order
-		 * 3) The first packet is not the next on in the sequence
-		 * 		a) We have exceeded the wait buffer
-		 * 		b) We wait
-		 */
-		//System.out.println(" Debug:" +(retNode != null) + " " + (retNode.seqNum == this.lastSeqNumber + 1)
-		//		+ " " + ( retNode.seqNum == 0 ) + " " +  (this.length > this.rtpSession.maxReorderBuffer)
-		//		+ " " + (this.lastSeqNumber < 0));
-
-		// Pop it off, null all references.
-		if( retNode != null && (retNode.seqNum == this.lastSeqNumber + 1 || retNode.seqNum == 0 
-					|| this.length > this.rtpSession.pktBufBehavior || this.lastSeqNumber < 0)) {
-			
-				
-			//if(tmpNode.pktCount == compLen) {
-			if(RTPSession.rtpDebugLevel > 7) {
-				System.out.println("<- PktBuffer.popOldestFrame() returns frame");
-			}
-			
-			DataFrame df = new DataFrame(retNode, this.p, 
-					rtpSession.appIntf.frameSize(oldest.pkt.getPayloadType()));
-			
-			//DataFrame df = new DataFrame(retNode, this.p, 1);
-			popFrameQueueCleanup(retNode, df.lastSeqNum);
-			
-			return df;
-		
-		} else {
-			// If we get here we have little to show for.
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println("<- PktBuffer.popOldestFrame() returns null " + retNode.seqNum + " " + this.lastSeqNumber);
-				this.debugPrint();
-			}
-			return null;
-		}
-	}
-	
-	/**
-	 * Cleans the packet buffer before returning the frame,
-	 * i.e. making sure the queue has a head etc.
-	 * 
-	 * @param retNode the node that is about to be popped
-	 * @param highestSeq the highest sequence number returned to the application
-	 */
-	private void popFrameQueueCleanup(PktBufNode retNode, int highestSeq) {
-		if(1 == length) {
-			//There's only one frame
-			newest = null;
-			oldest = null;
-		} else {
-			//There are more frames
-			oldest = oldest.prevFrameQueueNode;
-			oldest.nextFrameQueueNode = null;
-		}
-
-		// Update counters
-		length--;
-		
-		//Find the highest sequence number associated with this timestamp
-		this.lastSeqNumber = highestSeq;
-		this.lastTimestamp = retNode.timeStamp;
-	}
-	
-	/** 
-	 * Returns the length of the packetbuffer.
-	 * @return number of frames (complete or not) in packetbuffer.
-	 */
-	protected int getLength() {
-		return length;
-	}
-	
-	/**
-	 * Checks whether a packet is not too late, i.e. the next packet has already been returned.
-	 * @param timeStamp the RTP timestamp of the packet under consideration 
-	 * @param seqNum the sequence number of the packet under consideration
-	 * @return true if newer packets have not been handed to the application
-	 */
-	protected boolean pktOnTime(long timeStamp, int seqNum) {
-		if(this.lastSeqNumber == -1) {
-			// First packet
-			return true;
-		} else {			
-			if(seqNum >= this.lastSeqNumber) {
-				if(this.lastSeqNumber < 3 && timeStamp < this.lastTimestamp ) {
-					return false;
-				}
-			} else {
-				if(seqNum > 3 || timeStamp < this.lastTimestamp) {
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	/** 
-	 * Prints out the packet buffer, oldest node first (on top).
-	 */
-	protected void debugPrint() {
-		System.out.println("PktBuffer.debugPrint() : length "+length+" SSRC "+SSRC+" lastSeqNum:"+lastSeqNumber);
-		PktBufNode tmpNode = oldest;
-		int i = 0;
-		while(tmpNode != null) {
-			//String str = tmpNode.timeStamp.toString();
-			System.out.println("   " + i + " seqNum:"+tmpNode.seqNum+" timeStamp: " + tmpNode.timeStamp + " pktCount:" + tmpNode.pktCount );
-			i++;
-			tmpNode = tmpNode.prevFrameQueueNode;
-		}
-	}
-}
--- a/src/jlibrtp/README.txt	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-jlibrtp - Java RTP Library
-
-Kepp, Arne
-ak2618@columbia.edu
-
-Columbia University
-New York, NY 10027
-USA
-
-This library was started as a term project in VoIP Security, a class taught by 
-Prof. Henning Schulzrinne at Columbia University. Version 0.1 (not released as such)
-was written by Vaishnav Janardhan (vj2135@columbia.edu) and Arne Kepp (ak2618@columbia.edu).
-
-This version was rewritten by Arne Kepp, as a student project under the supervision of 
-Prof. Henning Schulzrinne, Columbia University.
-
-------Abstract
-jlibrtp is a library that implements the Real-Time Transport Protocol (RTP), 
-a well-established standard for streaming media across IP-based networks, in Java. 
-The purpose  of this library is to make it easy for application developers to 
-create applications for peer to peer streaming of audio, video and other data. 
-In addition, developers will need a protocol to establish contact with peers, 
-such as Session Initialization Protocol (SIP) and/or SDP.
-
-The library accepts any kind of binary data, handles packet parsing and reordering, 
-maintains a participant database and the control connection associated with the 
-protocol. The application is notified of received data through a callback-interface. 
-The library supports IPv4, IPv6 and multicast. It does currently not support encryption, 
-and should not be used in cases where confidentiality is important before this has 
-been remedied.
-
-Please refer to http://jlibrtp.org for more information and newer versions.
-
-The library requires Sun Microsystems Java 1.5.0 or greater, or equivalent.
-
-The Library is licensed under the GNU Lesser General Public License, see LICENSE.txt
-
-The demonstration programs can be compiled as follows:
-javac ./jlibrtpDemos/SoundSenderDemo.java jlibrtp/*.java
\ No newline at end of file
--- a/src/jlibrtp/RTCPAVPFIntf.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-package jlibrtp;
-
-
-/**
- * This is the callback interface for the AVPF profile (RFC 4585)
- * 
- * It is optional, you do not have to register it.
- * 
- * If there are specific events you wish to ignore,
- * you can simply implement empty functions.
- * 
- * These are all syncrhonous, make sure to return quickly
- * or do the handling in a new thread.
- * 
- * @author Arne Kepp
- */
-public interface RTCPAVPFIntf {	
-	
-	/**
-	 * This function is called when a 
-	 * Picture Loss Indication (PLI, FMT = 1) is received
-	 * 
-	 * @param ssrcPacketSender the SSRC of the participant reporting loss of picture
-	 */
-	public void PSFBPktPictureLossReceived(
-			long ssrcPacketSender);
-	
-	/**
-	 * This function is called when a
-	 * Slice Loss Indication (SLI, FMT=2) is received
-	 * 
-	 * @param ssrcPacketSender the SSRC of the participant reporting loss of slice(s)
-	 * @param sliceFirst macroblock address of first macroblock
-	 * @param sliceNumber number of lost macroblocks, in scan order
-	 * @param slicePictureId the six least significant bits of the picture identifier 
-	 */
-	public void PSFBPktSliceLossIndic(
-			long ssrcPacketSender,
-			int[] sliceFirst, int[] sliceNumber, int[] slicePictureId);
-	
-	/**
-	 * This function is called when a
-	 * Reference Picture Selection Indication (RPSI, FMT=3) is received
-	 * 
-	 * @param ssrcPacketSender the SSRC of the participant reporting the selection
-	 * @param rpsiPayloadType the RTP payload type related to the RPSI bit string
-	 * @param rpsiBitString the RPSI information as natively defined by the video codec
-	 * @param rpsiPaddingBits the number of padding bits at the end of the string
-	 */
-	public void PSFBPktRefPictureSelIndic(
-			long ssrcPacketSender,
-			int rpsiPayloadType, byte[] rpsiBitString, int rpsiPaddingBits);
-	
-	/**
-	 * This function is called when a 
-	 * Transport Layer Feedback Messages is received
-	 * 
-	 * @param ssrcPacketSender
-	 * @param alfBitString
-	 */
-	public void PSFBPktAppLayerFBReceived(
-			long ssrcPacketSender,
-			byte[] alfBitString);
-
-	/**
-	 * This function is called when a 
-	 * Transport Layer Feedback Messages is received
-	 * 
-	 * @param ssrcPacketSender 
-	 * @param FMT 1: NACK, 0,2-30: unassigned, 31: reserved
-	 * @param packetID the RTP sequence number of the lost packet
-	 * @param bitmaskLostPackets the bitmask of following lost packets
-	 */
-	public void RTPFBPktReceived(
-			long ssrcPacketSender,
-			int FMT, int[] packetID, int[] bitmaskLostPackets);
-}
\ No newline at end of file
--- a/src/jlibrtp/RTCPAppIntf.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-package jlibrtp;
-
-
-/**
- * This is the callback interface for RTCP packets.
- * 
- * It is optional, you do not have to register it.
- * 
- * If there are specific events you wish to ignore,
- * you can simply implement empty functions.
- * 
- * These are all syncrhonous, make sure to return quickly
- * or do the handling in a new thread.
- * 
- * @author Arne Kepp
- */
-public interface RTCPAppIntf {
-	
-	/**
-	 * This function is called whenever a Sender Report (SR) packet is received
-	 * and returns unmodified values.
-	 *  
-	 * A sender report may optionally include Receiver Reports (RR), 
-	 * which are returned as arrays. Index i corresponds to the same report
-	 * throughout all of the arrays.
-	 * 
-	 * @param ssrc the (SR) SSRC of the sender
-	 * @param ntpHighOrder (SR) NTP high order
-	 * @param ntpLowOrder (SR) NTP low order
-	 * @param rtpTimestamp (SR) RTP timestamp corresponding to the NTP timestamp
-	 * @param packetCount (SR) Packets sent since start of session
-	 * @param octetCount (SR) Octets sent since start of session
-	 * @param reporteeSsrc (RR) SSRC of sender the receiver is reporting in
-	 * @param lossFraction (RR) Loss fraction, see RFC 3550
-	 * @param cumulPacketsLost (RR) Cumulative number of packets lost
-	 * @param extHighSeq (RR) Extended highest sequence RTP packet received
-	 * @param interArrivalJitter (RR) Interarrival jitter, see RFC 3550
-	 * @param lastSRTimeStamp (RR) RTP timestamp when last SR was received 
-	 * @param delayLastSR (RR) Delay, in RTP, since last SR was received
-	 */
-	public void SRPktReceived(long ssrc, long ntpHighOrder, long ntpLowOrder, 
-			long rtpTimestamp, long packetCount, long octetCount,
-			// Get the receiver reports, if any
-			long[] reporteeSsrc, int[] lossFraction, int[] cumulPacketsLost, long[] extHighSeq, 
-			long[] interArrivalJitter, long[] lastSRTimeStamp, long[] delayLastSR);
-	
-	/**
-	 * This function is called whenever a Receiver Report (SR) packet is received
-	 * and returns unmodified values.
-	 * 
-	 * A receiver report may optionally include report blocks, 
-	 * which are returned as arrays. Index i corresponds to the same report
-	 * throughout all of the arrays.
-	 * 
-	 * @param reporterSsrc SSRC of the receiver reporting
-	 * @param reporteeSsrc (RR) SSRC of sender the receiver is reporting in
-	 * @param lossFraction (RR) Loss fraction, see RFC 3550
-	 * @param cumulPacketsLost (RR) Cumulative number of packets lost
-	 * @param extHighSeq (RR) Extended highest sequence RTP packet received
-	 * @param interArrivalJitter (RR) Interarrival jitter, see RFC 3550
-	 * @param lastSRTimeStamp (RR) RTP timestamp when last SR was received 
-	 * @param delayLastSR (RR) Delay, in RTP, since last SR was received
-	 */
-	public void RRPktReceived(long reporterSsrc, long[] reporteeSsrc, 
-			int[] lossFraction, int[] cumulPacketsLost, long[] extHighSeq, 
-			long[] interArrivalJitter, long[] lastSRTimeStamp, long[] delayLastSR);
-	
-	/**
-	 * This function is called whenever a Source Description (SDES) packet is received.
-	 * 
-	 * It currently returns the updated participants AFTER they have been updated.
-	 * 
-	 * @param relevantParticipants participants mentioned in the SDES packet
-	 */
-	public void SDESPktReceived(Participant[] relevantParticipants);
-	
-	/**
-	 * This function is called whenever a Bye (BYE) packet is received.
-	 * 
-	 * The participants will automatically be deleted from the participant
-	 * database after some time, but in the mean time the application may 
-	 * still receive RTP  packets from this source.
-	 * 
-	 * @param relevantParticipants participants whose SSRC was in the packet
-	 * @param reason the reason provided in the packet
-	 */
-	public void BYEPktReceived(Participant[] relevantParticipants, String reason);
-	
-	
-	/**
-	 * This function is called whenever an Application (APP) packet is received.
-	 * 
-	 * @param part the participant associated with the SSRC
-	 * @param subtype specified in the packet
-	 * @param name ASCII description of packet
-	 * @param data in the packet
-	 */
-	public void APPPktReceived(Participant part, int subtype, byte[] name, byte[] data);
-}
\ No newline at end of file
--- a/src/jlibrtp/RTCPReceiverThread.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,369 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.InetSocketAddress;
-import java.util.Enumeration;
-import java.util.Iterator;
-
-/**
- * This thread hangs on the RTCP socket and waits for new packets
- * 
- * @author Arne Kepp
- *
- */
-public class RTCPReceiverThread extends Thread {
-	/** Parent RTP Session */
-	private RTPSession rtpSession = null;
-	/** Parent RTCP Session */
-	private RTCPSession rtcpSession = null;
-	
-	/**
-	 * Constructor for new thread
-	 * @param rtcpSession parent RTCP session
-	 * @param rtpSession parent RTP session
-	 */
-	RTCPReceiverThread(RTCPSession rtcpSession, RTPSession rtpSession) {
-		this.rtpSession = rtpSession;
-		this.rtcpSession = rtcpSession;
-		
-		if(RTPSession.rtpDebugLevel > 1) {
-			System.out.println("<-> RTCPReceiverThread created");
-		} 
-
-	}
-	
-	/**
-	 * Find out whether a participant with this SSRC is known.
-	 * 
-	 * If the user is unknown, and the system is operating in unicast mode,
-	 * try to match the ip-address of the sender to the ip address of a
-	 * previously unmatched target
-	 * 
-	 * @param ssrc the SSRC of the participant
-	 * @param packet the packet that notified us
-	 * @return the relevant participant, possibly newly created
-	 */
-	private Participant findParticipant(long ssrc, DatagramPacket packet) {
-		Participant p = rtpSession.partDb.getParticipant(ssrc);
-		if(p == null) {
-			Enumeration<Participant> enu = rtpSession.partDb.getParticipants();
-			while(enu.hasMoreElements()) {
-				Participant tmp = (Participant) enu.nextElement();
-				if(tmp.ssrc < 0 && 
-						(tmp.rtcpAddress.getAddress().equals(packet.getAddress())
-						|| tmp.rtpAddress.getAddress().equals(packet.getAddress()))) {
-					
-					// Best guess
-					System.out.println("RTCPReceiverThread: Got an unexpected packet from SSRC:" 
-							+ ssrc  + " @" + packet.getAddress().toString() + ", WAS able to match it." );
-					
-					tmp.ssrc = ssrc;
-					return tmp;
-				}
-			}
-			// Create an unknown sender
-			System.out.println("RTCPReceiverThread: Got an unexpected packet from SSRC:" 
-					+ ssrc  + " @" + packet.getAddress().toString() + ", was NOT able to match it." );
-			p = new Participant((InetSocketAddress) null, (InetSocketAddress) packet.getSocketAddress(), ssrc);
-			rtpSession.partDb.addParticipant(2,p);
-		}
-		return p;
-	}
-	
-	
-	/**
-	 * Parse a received UDP packet
-	 * 
-	 * Perform the header checks and extract the RTCP packets in it
-	 * 
-	 * @param packet the packet to be parsed
-	 * @return -1 if there was a problem, 0 if successfully parsed
-	 */
-	private int parsePacket(DatagramPacket packet) {
-
-		if(packet.getLength() % 4 != 0) {
-			if(RTPSession.rtcpDebugLevel > 2) {
-				System.out.println("RTCPReceiverThread.parsePacket got packet that had length " + packet.getLength());
-			}
-			return -1;
-		} else {
-			byte[] rawPkt = packet.getData();
-
-			// Parse the received compound RTCP (?) packet
-			CompRtcpPkt compPkt = new CompRtcpPkt(rawPkt, packet.getLength(), 
-					(InetSocketAddress) packet.getSocketAddress(), rtpSession);
-
-			if(this.rtpSession.debugAppIntf != null) {
-				String intfStr; 
-
-				if(rtpSession.mcSession) {
-					intfStr = this.rtcpSession.rtcpMCSock.getLocalSocketAddress().toString();
-				} else {
-					intfStr = this.rtpSession.rtpSock.getLocalSocketAddress().toString();
-				}
-
-				if( compPkt.problem == 0) {
-					String str = new String("Received compound RTCP packet of size " + packet.getLength() + 
-							" from " + packet.getSocketAddress().toString() + " via " + intfStr
-							+ " containing " + compPkt.rtcpPkts.size() + " packets" );
-
-					this.rtpSession.debugAppIntf.packetReceived(1, 
-							(InetSocketAddress) packet.getSocketAddress(), str);
-				} else {
-					String str = new String("Received invalid RTCP packet of size " + packet.getLength() + 
-							" from " + packet.getSocketAddress().toString() + " via " +  intfStr
-							+ ": " + this.debugErrorString(compPkt.problem) );
-
-					this.rtpSession.debugAppIntf.packetReceived(-2, 
-							(InetSocketAddress) packet.getSocketAddress(), str);
-				}
-			}
-			
-			if(RTPSession.rtcpDebugLevel > 5) {
-				Iterator<RtcpPkt> iter = compPkt.rtcpPkts.iterator();
-				String str = " ";
-				while(iter.hasNext()) {
-					RtcpPkt aPkt = iter.next();
-					str += (aPkt.getClass().toString() + ":"+aPkt.itemCount+ ", ");
-				}
-				System.out.println("<-> RTCPReceiverThread.parsePacket() from " + packet.getSocketAddress().toString() + str);
-			}
-			
-
-			//Loop over the information
-			Iterator iter = compPkt.rtcpPkts.iterator();
-
-			long curTime = System.currentTimeMillis();
-
-			while(iter.hasNext()) {
-				RtcpPkt aPkt = (RtcpPkt) iter.next();
-
-				// Our own packets should already have been filtered out.
-				if(aPkt.ssrc == rtpSession.ssrc) {
-					System.out.println("RTCPReceiverThread() received RTCP packet" 
-							+ " with conflicting SSRC from " + packet.getSocketAddress().toString());
-					rtpSession.resolveSsrcConflict();
-					return -1;
-				}
-
-				/**        Receiver Reports        **/
-				if(	aPkt.getClass() == RtcpPktRR.class) {
-					RtcpPktRR rrPkt = (RtcpPktRR) aPkt;
-
-					Participant p = findParticipant(rrPkt.ssrc, packet);
-					p.lastRtcpPkt = curTime;
-
-					if(rtpSession.rtcpAppIntf != null) {
-						rtpSession.rtcpAppIntf.RRPktReceived(rrPkt.ssrc, rrPkt.reporteeSsrc, 
-								rrPkt.lossFraction, rrPkt.lostPktCount, rrPkt.extHighSeqRecv,
-								rrPkt.interArvJitter, rrPkt.timeStampLSR, rrPkt.delaySR);
-					}
-
-					/**        Sender Reports        **/
-				} else if(aPkt.getClass() == RtcpPktSR.class) {
-					RtcpPktSR srPkt = (RtcpPktSR) aPkt;
-
-					Participant p = findParticipant(srPkt.ssrc, packet);
-					p.lastRtcpPkt = curTime;
-
-					if(p != null) {
-
-						if(p.ntpGradient < 0 && p.lastNtpTs1 > -1) {
-							//Calculate gradient NTP vs RTP
-							long newTime = StaticProcs.undoNtpMess(srPkt.ntpTs1, srPkt.ntpTs2);
-							p.ntpGradient = ((double) (newTime - p.ntpOffset))/((double) srPkt.rtpTs - p.lastSRRtpTs);
-							if(RTPSession.rtcpDebugLevel > 4) {
-								System.out.println("RTCPReceiverThread calculated NTP vs RTP gradient: " + Double.toString(p.ntpGradient));
-							}
-						} else {
-							// Calculate sum of ntpTs1 and ntpTs2 in milliseconds
-							p.ntpOffset = StaticProcs.undoNtpMess(srPkt.ntpTs1, srPkt.ntpTs2);
-							p.lastNtpTs1 = srPkt.ntpTs1;
-							p.lastNtpTs2 = srPkt.ntpTs2;
-							p.lastSRRtpTs = srPkt.rtpTs;
-						}
-
-						// For the next RR
-						p.timeReceivedLSR = curTime;
-						p.setTimeStampLSR(srPkt.ntpTs1,srPkt.ntpTs2);
-
-					}
-
-
-					if(rtpSession.rtcpAppIntf != null) {
-						if(srPkt.rReports != null) {
-							rtpSession.rtcpAppIntf.SRPktReceived(srPkt.ssrc, srPkt.ntpTs1, srPkt.ntpTs2, 
-									srPkt.rtpTs, srPkt.sendersPktCount, srPkt.sendersPktCount,
-									srPkt.rReports.reporteeSsrc, srPkt.rReports.lossFraction, srPkt.rReports.lostPktCount,
-									srPkt.rReports.extHighSeqRecv, srPkt.rReports.interArvJitter, srPkt.rReports.timeStampLSR,
-									srPkt.rReports.delaySR);
-						} else {
-							rtpSession.rtcpAppIntf.SRPktReceived(srPkt.ssrc, srPkt.ntpTs1, srPkt.ntpTs2, 
-									srPkt.rtpTs, srPkt.sendersPktCount, srPkt.sendersPktCount,
-									null, null, null,
-									null, null, null,
-									null);
-						}
-					}
-
-					/**        Source Descriptions       **/
-				} else if(aPkt.getClass() == RtcpPktSDES.class) {
-					RtcpPktSDES sdesPkt = (RtcpPktSDES) aPkt;				
-
-					// The the participant database is updated
-					// when the SDES packet is reconstructed by CompRtcpPkt	
-					if(rtpSession.rtcpAppIntf != null) {
-						rtpSession.rtcpAppIntf.SDESPktReceived(sdesPkt.participants);
-					}
-
-					/**        Bye Packets       **/
-				} else if(aPkt.getClass() == RtcpPktBYE.class) {
-					RtcpPktBYE byePkt = (RtcpPktBYE) aPkt;
-
-					long time = System.currentTimeMillis();
-					Participant[] partArray = new Participant[byePkt.ssrcArray.length];
-
-					for(int i=0; i<byePkt.ssrcArray.length; i++) {
-						partArray[i] = rtpSession.partDb.getParticipant(byePkt.ssrcArray[i]);
-						if(partArray[i] != null)
-							partArray[i].timestampBYE = time;
-					}
-
-					if(rtpSession.rtcpAppIntf != null) {
-						rtpSession.rtcpAppIntf.BYEPktReceived(partArray, new String(byePkt.reason));
-					}
-					
-					/**        Application specific Packets       **/
-				} else if(aPkt.getClass() == RtcpPktAPP.class) {
-					RtcpPktAPP appPkt = (RtcpPktAPP) aPkt;
-
-					Participant part = findParticipant(appPkt.ssrc, packet);
-					
-					if(rtpSession.rtcpAppIntf != null) {
-						rtpSession.rtcpAppIntf.APPPktReceived(part, appPkt.itemCount, appPkt.pktName, appPkt.pktData);
-					}
-			}
-
-
-
-			}
-		}
-		return 0;
-	}
-	
-	/**
-	 * Returns a legible message when an error occurs
-	 * 
-	 * @param errorCode the internal error code, commonly negative of packet type
-	 * @return a string that is hopefully somewhat informative
-	 */
-	private String debugErrorString(int errorCode) {
-		String aStr = "";
-		switch(errorCode) {
-			case -1: aStr = "The first packet was not of type SR or RR."; break;
-			case -2: aStr = "The padding bit was set for the first packet."; break;
-			case -200: aStr = " Error parsing Sender Report packet."; break;
-			case -201: aStr = " Error parsing Receiver Report packet."; break;
-			case -202: aStr = " Error parsing SDES packet"; break;
-			case -203: aStr = " Error parsing BYE packet."; break;
-			case -204: aStr = " Error parsing Application specific packet."; break;
-			case -205: aStr = " Error parsing RTP Feedback packet."; break;
-			case -206: aStr = " Error parsing Payload-Specific Feedback packet."; break;
-		default:
-			aStr = "Unknown error code " + errorCode + ".";
-		}
-		
-		return aStr;
-	}
-
-	/**
-	 * Start the RTCP receiver thread.
-	 * 
-	 * It will
-	 * 1) run when it receives a packet 
-	 * 2) parse the packet
-	 * 3) call any relevant callback functions, update database
-	 * 4) block until the next one arrives.
-	 */
-	public void run() {
-		if(RTPSession.rtcpDebugLevel > 1) {
-			if(rtpSession.mcSession) {
-				System.out.println("-> RTCPReceiverThread.run() starting on MC " + rtcpSession.rtcpMCSock.getLocalPort() );
-			} else {
-				System.out.println("-> RTCPReceiverThread.run() starting on " + rtcpSession.rtcpSock.getLocalPort() );
-			}
-		}
-
-		while(!rtpSession.endSession) {
-			
-			if(RTPSession.rtcpDebugLevel > 4) {
-				if(rtpSession.mcSession) {
-					System.out.println("-> RTCPReceiverThread.run() waiting for packet on MC " + rtcpSession.rtcpMCSock.getLocalPort() );
-				} else {
-					System.out.println("-> RTCPReceiverThread.run() waiting for packet on " + rtcpSession.rtcpSock.getLocalPort() );
-				}
-			}
-
-			// Prepare a packet
-			byte[] rawPkt = new byte[1500];
-			DatagramPacket packet = new DatagramPacket(rawPkt, rawPkt.length);
-
-			// Wait for it to arrive
-			if(! rtpSession.mcSession) {
-				//Unicast
-				try {
-					rtcpSession.rtcpSock.receive(packet);
-				} catch (IOException e) {
-					if(!rtpSession.endSession) {
-						e.printStackTrace();
-					} else {
-						continue;
-					}
-				}
-			} else {
-				//Multicast
-				try {
-					rtcpSession.rtcpMCSock.receive(packet);
-				} catch (IOException e) {
-					if(!rtpSession.endSession) {
-						e.printStackTrace();
-					} else {
-						continue;
-					}
-				}
-			}
-			
-			// Check whether this is one of our own
-			if( (rtpSession.mcSession && ! packet.getSocketAddress().equals(rtcpSession.rtcpMCSock) )
-					|| ! packet.getSocketAddress().equals(rtcpSession.rtcpSock) ) {
-				//System.out.println("Packet received from: " + packet.getSocketAddress().toString());
-				parsePacket(packet);
-				//rtpSession.partDb.debugPrint();
-			}			
-		}
-		
-		if(RTPSession.rtcpDebugLevel > 1) {
-			System.out.println("<-> RTCPReceiverThread terminating");
-		}
-	}
-
-}
--- a/src/jlibrtp/RTCPSenderThread.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,457 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.DatagramPacket;
-import java.net.InetSocketAddress;
-import java.util.*;
-
-/**
- * This thread sends scheduled RTCP packets 
- * 
- * It also performs maintenance of various queues and the participant
- * database.
- * 
- * @author Arne Kepp
- *
- */
-public class RTCPSenderThread extends Thread {
-	/** Parent RTP Session */
-	private RTPSession rtpSession = null;
-	/** Parent RTCP Session */
-	private RTCPSession rtcpSession = null;
-	
-	/** Whether we have sent byes for the last conflict */
-	private boolean byesSent = false;
-	
-	/**
-	 * Constructor for new thread
-	 * @param rtcpSession parent RTCP session
-	 * @param rtpSession parent RTP session
-	 */
-	protected RTCPSenderThread(RTCPSession rtcpSession, RTPSession rtpSession) {
-		this.rtpSession = rtpSession;
-		this.rtcpSession = rtcpSession;
-		if(RTPSession.rtpDebugLevel > 1) {
-			System.out.println("<-> RTCPSenderThread created");
-		} 
-	}
-	
-	/**
-	 * Send BYE messages to all the relevant participants
-	 *
-	 */
-	protected void sendByes() {
-		// Create the packet
-		CompRtcpPkt compPkt = new CompRtcpPkt();
-		
-		//Need a SR for validation
-		RtcpPktSR srPkt = new RtcpPktSR(this.rtpSession.ssrc, 
-				this.rtpSession.sentPktCount, this.rtpSession.sentOctetCount, null);
-		compPkt.addPacket(srPkt);
-		
-		byte[] reasonBytes;
-		
-		//Add the actualy BYE Pkt
-		long[] ssrcArray = {this.rtpSession.ssrc};
-		if(rtpSession.conflict) {
-			reasonBytes = "SSRC collision".getBytes();
-		} else {
-			reasonBytes = "jlibrtp says bye bye!".getBytes();
-		}
-		RtcpPktBYE byePkt = new RtcpPktBYE( ssrcArray, reasonBytes);
-		
-		compPkt.addPacket(byePkt);
-		
-		// Send it off
-		if(rtpSession.mcSession) {
-			mcSendCompRtcpPkt(compPkt);
-		} else {
-			Iterator<Participant> iter = rtpSession.partDb.getUnicastReceivers();
-		
-			while(iter.hasNext()) {
-				Participant part = (Participant) iter.next();
-				if(part.rtcpAddress != null)
-					sendCompRtcpPkt(compPkt, part.rtcpAddress);
-			}
-			//System.out.println("SENT BYE PACKETS!!!!!");
-		}
-	}
-	
-	/**
-	 * Multicast version of sending a Compound RTCP packet
-	 * 
-	 * @param pkt the packet to best
-	 * @return 0 is successful, -1 otherwise
-	 */
-	protected int mcSendCompRtcpPkt(CompRtcpPkt pkt) {
-		byte[] pktBytes = pkt.encode();
-		DatagramPacket packet;
-		
-		// Create datagram
-		try {
-			packet = new DatagramPacket(pktBytes,pktBytes.length,rtpSession.mcGroup,rtcpSession.rtcpMCSock.getPort());
-		} catch (Exception e) {
-			System.out.println("RCTPSenderThread.MCSendCompRtcpPkt() packet creation failed.");
-			e.printStackTrace();
-			return -1;
-		}
-		
-		// Send packet
-		if(RTPSession.rtcpDebugLevel > 5) {
-			System.out.println("<-> RTCPSenderThread.SendCompRtcpPkt() multicast");
-		}
-		try {
-			rtcpSession.rtcpMCSock.send(packet);
-			//Debug
-			if(this.rtpSession.debugAppIntf != null) {
-				this.rtpSession.debugAppIntf.packetSent(3, (InetSocketAddress) packet.getSocketAddress(), 
-						new String("Sent multicast RTCP packet of size " + packet.getLength() + 
-								" to " + packet.getSocketAddress().toString() + " via " 
-								+ this.rtcpSession.rtcpMCSock.getLocalSocketAddress().toString()));
-			}
-		} catch (Exception e) {
-			System.out.println("RCTPSenderThread.MCSendCompRtcpPkt() multicast failed.");
-			e.printStackTrace();
-			return -1;
-		}
-		return packet.getLength();
-	}
-	
-	/**
-	 * Unicast version of sending a Compound RTCP packet
-	 * 
-	 * @param pkt the packet to best
-	 * @param receiver the socket address of the recipient
-	 * @return 0 is successful, -1 otherwise
-	 */
-	protected int sendCompRtcpPkt(CompRtcpPkt pkt, InetSocketAddress receiver) {
-		byte[] pktBytes = pkt.encode();
-		DatagramPacket packet;
-		
-		//Create datagram
-		try {
-			//System.out.println("receiver: " + receiver);
-			packet = new DatagramPacket(pktBytes,pktBytes.length,receiver);
-		} catch (Exception e) {
-			System.out.println("RCTPSenderThread.SendCompRtcpPkt() packet creation failed.");
-			e.printStackTrace();
-			return -1;
-		}
-		
-		//Send packet
-		if(RTPSession.rtcpDebugLevel > 5) {
-			Iterator<RtcpPkt> iter = pkt.rtcpPkts.iterator();
-			String str = " ";
-			while(iter.hasNext()) {
-				RtcpPkt aPkt = iter.next();
-				str += (aPkt.getClass().toString() + ":"+aPkt.itemCount+ ", ");
-			}
-			System.out.println("<-> RTCPSenderThread.SendCompRtcpPkt() unicast to " + receiver + str);
-		}
-		try {
-			rtcpSession.rtcpSock.send(packet);
-			//Debug
-			if(this.rtpSession.debugAppIntf != null) {
-				this.rtpSession.debugAppIntf.packetSent(2, (InetSocketAddress) packet.getSocketAddress(), 
-						new String("Sent unicast RTCP packet of size " + packet.getLength() + 
-								" to " + packet.getSocketAddress().toString() + " via " 
-								+ this.rtcpSession.rtcpSock.getLocalSocketAddress().toString()));
-			}
-		} catch (Exception e) {
-			System.out.println("RTCPSenderThread.SendCompRtcpPkt() unicast failed.");
-			e.printStackTrace();
-			return -1;
-		}
-		return packet.getLength();
-	}
-	
-	/**
-	 * Check whether we can send an immediate feedback packet to this person
-	 * @param ssrc SSRC of participant
-	 */
-	protected void reconsiderTiming(long ssrc) {
-		Participant part =  this.rtpSession.partDb.getParticipant(ssrc);
-		
-		if( part != null && this.rtcpSession.fbSendImmediately()) {
-			CompRtcpPkt compPkt = preparePacket(part, false);
-			/*********** Send the packet ***********/
-			// Keep track of sent packet length for average;
-			int datagramLength;
-			if(rtpSession.mcSession) {
-				datagramLength = this.mcSendCompRtcpPkt(compPkt);
-			} else {
-				//part.debugPrint();
-				datagramLength = this.sendCompRtcpPkt(compPkt, part.rtcpAddress);
-			}
-			/*********** Administrative tasks ***********/			
-			//Update average packet size
-			if(datagramLength > 0) {
-				rtcpSession.updateAvgPacket(datagramLength);
-			}
-		} else if(part != null 
-				&& this.rtcpSession.fbAllowEarly 
-				&& this.rtcpSession.fbSendEarly()) {
-			
-			// Make sure we dont do it too often
-			this.rtcpSession.fbAllowEarly = false;
-			
-			CompRtcpPkt compPkt = preparePacket(part, true);
-			/*********** Send the packet ***********/
-			// Keep track of sent packet length for average;
-			int datagramLength;
-			if(rtpSession.mcSession) {
-				datagramLength = this.mcSendCompRtcpPkt(compPkt);
-			} else {
-				//part.debugPrint();
-				datagramLength = this.sendCompRtcpPkt(compPkt, part.rtcpAddress);
-			}
-			/*********** Administrative tasks ***********/			
-			//Update average packet size
-			if(datagramLength > 0) {
-				rtcpSession.updateAvgPacket(datagramLength);
-			}
-			rtcpSession.calculateDelay();
-		}
-		
-		//Out of luck, fb message will have to go with next regular packet
-		//Sleep for the remaining time.
-		this.rtcpSession.nextDelay -= System.currentTimeMillis() - this.rtcpSession.prevTime;
-		if(this.rtcpSession.nextDelay < 0)
-			this.rtcpSession.nextDelay = 0;
-		
-	}
-	
-	/** 
-	 * Prepare a packet. The output depends on the participant and how the
-	 * packet is scheduled.
-	 * 
-	 * @param part the participant to report to
-	 * @param regular whether this is a regularly, or early scheduled RTCP packet
-	 * @return compound RTCP packet
-	 */
-	protected CompRtcpPkt preparePacket(Participant part, boolean regular) {
-		/*********** Figure out what we are going to send ***********/
-		// Check whether this person has sent RTP packets since the last RR.
-		boolean incRR = false;
-		if(part.secondLastRtcpRRPkt > part.lastRtcpRRPkt) {
-			incRR = true;
-			part.secondLastRtcpRRPkt = part.lastRtcpRRPkt;
-			part.lastRtcpRRPkt = System.currentTimeMillis();
-		}
-		
-		// Are we sending packets? -> add SR
-		boolean incSR = false;
-		if(rtpSession.sentPktCount > 0 && regular) {
-			incSR = true;
-		}
-		
-		
-		/*********** Actually create the packet ***********/
-		// Create compound packet
-		CompRtcpPkt compPkt = new CompRtcpPkt();
-		
-		//If we're sending packets we'll use a SR for header
-		if(incSR) {
-			RtcpPktSR srPkt = new RtcpPktSR(this.rtpSession.ssrc, 
-					this.rtpSession.sentPktCount, this.rtpSession.sentOctetCount, null);
-			compPkt.addPacket(srPkt);
-			
-			
-			if(part.ssrc > 0) {
-				RtcpPkt[] ar = this.rtcpSession.getFromFbQueue(part.ssrc);
-				if(ar != null) {
-					for(int i=0; i<ar.length; i++) {
-						compPkt.addPacket(ar[i]);
-					}
-				}
-			}
-			
-		}
-		
-		//If we got anything from this participant since we sent the 2nd to last RtcpPkt
-		if(incRR || !incSR) {
-			Participant[] partArray = {part};
-			
-			if(part.receivedPkts < 1)
-				partArray = null;
-			
-			RtcpPktRR rrPkt = new RtcpPktRR(partArray, rtpSession.ssrc);
-			compPkt.addPacket(rrPkt);
-			
-			if( !incSR && part.ssrc > 0) {
-				RtcpPkt[] ar = this.rtcpSession.getFromFbQueue(part.ssrc);
-				if(ar != null) {
-					for(int i=0; i<ar.length; i++) {
-						compPkt.addPacket(ar[i]);
-					}
-				}
-			}
-		}
-		
-		// APP packets
-		if(regular && part.ssrc > 0) {
-			RtcpPkt[] ar = this.rtcpSession.getFromAppQueue(part.ssrc);
-			if(ar != null) {
-				for(int i=0; i<ar.length; i++) {
-					compPkt.addPacket(ar[i]);
-				}
-			} else {
-				//Nope
-			}
-		}
-		
-		
-		// For now we'll stick the SDES on every time, and only for us
-		//if(regular) {
-			RtcpPktSDES sdesPkt = new RtcpPktSDES(true, this.rtpSession, null);
-			compPkt.addPacket(sdesPkt);
-		//}
-		
-		return compPkt;
-	}
-	
-	/**
-	 * Start the RTCP sender thread.
-	 * 
-	 * RFC 4585 is more complicated, but in general it will
-	 * 1) Wait a precalculated amount of time
-	 * 2) Determine the next RTCP recipient
-	 * 3) Construct a compound packet with all the relevant information
-	 * 4) Send the packet
-	 * 5) Calculate next delay before going to sleep
-	 */
-	public void run() {
-		if(RTPSession.rtcpDebugLevel > 1) {
-			System.out.println("<-> RTCPSenderThread running");
-		}
-		
-		// Give the application a chance to register some participants
-		try { Thread.sleep(10); } 
-		catch (Exception e) { System.out.println("RTCPSenderThread didn't get any initial rest."); }
-		
-		// Set up an iterator for the member list
-		Enumeration<Participant> enu = null;
-		Iterator<Participant> iter = null;
-		
-		// TODO Change to rtcpReceivers
-		if(rtpSession.mcSession) {
-			enu = rtpSession.partDb.getParticipants();
-		} else {
-			iter = rtpSession.partDb.getUnicastReceivers();
-		}
-		while(! rtpSession.endSession) {
-			if(RTPSession.rtcpDebugLevel > 5) {
-				System.out.println("<-> RTCPSenderThread sleeping for " +rtcpSession.nextDelay+" ms");
-			}
-			
-			try { Thread.sleep(rtcpSession.nextDelay); } 
-			catch (Exception e) { 
-				System.out.println("RTCPSenderThread Exception message:" + e.getMessage());
-				// Is the party over?
-				if(this.rtpSession.endSession) {
-					continue;
-				}
-				
-				if(rtcpSession.fbWaiting != -1) {
-					reconsiderTiming(rtcpSession.fbWaiting);
-					continue;
-				}
-			}
-			
-			/** Came here the regular way */
-			this.rtcpSession.fbAllowEarly = true;
-			
-				
-			if(RTPSession.rtcpDebugLevel > 5) {
-				System.out.println("<-> RTCPSenderThread waking up");
-			}
-			
-			// Regenerate nextDelay, before anything happens.
-			rtcpSession.calculateDelay();
-			
-			// We'll wait here until a conflict (if any) has been resolved,
-			// so that the bye packets for our current SSRC can be sent.
-			if(rtpSession.conflict) {
-				if(! this.byesSent) {
-					sendByes();
-					this.byesSent = true;
-				}
-				continue;
-			}
-			this.byesSent = false;
-						
-			//Grab the next person
-			Participant part = null;
-
-			//Multicast
-			if(this.rtpSession.mcSession) {
-				if(! enu.hasMoreElements())
-					enu = rtpSession.partDb.getParticipants();
-				
-				if( enu.hasMoreElements() ) {
-					part = enu.nextElement();
-				} else {
-					continue;
-				}
-				
-			//Unicast
-			} else {
-				if(! iter.hasNext()) {
-					iter = rtpSession.partDb.getUnicastReceivers();
-				}
-				
-				if(iter.hasNext() ) {
-					while( iter.hasNext() && (part == null || part.rtcpAddress == null)) {
-						part = iter.next();
-					}
-				}
-				
-				if(part == null || part.rtcpAddress == null)
-					continue;
-			}
-			
-			CompRtcpPkt compPkt = preparePacket(part, true);
-			
-			/*********** Send the packet ***********/
-			// Keep track of sent packet length for average;
-			int datagramLength;
-			if(rtpSession.mcSession) {
-				datagramLength = this.mcSendCompRtcpPkt(compPkt);
-			} else {
-				//part.debugPrint();
-				datagramLength = this.sendCompRtcpPkt(compPkt, part.rtcpAddress);
-			}
-			
-			/*********** Administrative tasks ***********/			
-			//Update average packet size
-			if(datagramLength > 0) {
-				rtcpSession.updateAvgPacket(datagramLength);
-			}
-		}
-
-		// Be polite, say Bye to everone
-		sendByes();
-		try { Thread.sleep(200);} catch(Exception e) {}
-		
-		if(RTPSession.rtcpDebugLevel > 0) {
-			System.out.println("<-> RTCPSenderThread terminating");
-		}
-	}
-}
--- a/src/jlibrtp/RTCPSession.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,527 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.util.Enumeration;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.MulticastSocket;
-import java.util.LinkedList;
-import java.util.Hashtable;
-import java.util.ListIterator;
-import java.util.Arrays;
-
-
-/**
- * This class acts as an organizer for most of the information
- * and functions pertaining to RTCP packet generation and reception 
- * 
- * @author Arne Kepp
- *
- */
-public class RTCPSession {
-	/** Parent session */
-	protected RTPSession rtpSession = null;
-	
-	/** Unicast socket */
-	protected DatagramSocket rtcpSock = null;
-	/** Multicast socket */
-	protected MulticastSocket rtcpMCSock = null;
-	/** Multicast group */
-	protected InetAddress mcGroup = null;
-
-	/** RTCP Receiver thread */
-	protected RTCPReceiverThread recvThrd = null;
-	/** RTCP Sender thread */
-	protected RTCPSenderThread senderThrd = null;
-	
-	/** Previous time a delay was calculated */
-	protected long prevTime = System.currentTimeMillis();
-	/** Delay between RTCP transmissions, in ms. Initialized in start() */
-	protected int nextDelay = -1; //
-	/** The average compound RTCP packet size, in octets, including UDP and IP headers */
-	protected int avgPktSize = 200; //
-	/** Pessimistic case estimate of the current number of senders */
-	protected int senderCount = 1;
-	/** Whether next RTCP packet can be sent early */
-	protected boolean fbAllowEarly = false;
-	/** Feedback queue , index is SSRC of target */
-	protected Hashtable<Long, LinkedList<RtcpPkt>> fbQueue = null;
-	/** APP queue , index is SSRC of target */
-	protected Hashtable<Long, LinkedList<RtcpPktAPP>> appQueue = null;
-	/** Are we just starting up? */
-	protected boolean initial = true;
-	/** Is there a feedback packet waiting? SSRC of destination */
-	protected long fbWaiting = -1;
-
-	/**
-	 * Constructor for unicast sessions
-	 * 
-	 * @param parent RTPSession that started this
-	 * @param rtcpSocket the socket to use for listening and sending
-	 */
-	protected RTCPSession(RTPSession parent, DatagramSocket rtcpSocket) {
-		this.rtcpSock = rtcpSocket;
-		rtpSession = parent;
-	}
-
-	/**
-	 * Constructor for multicast sessions
-	 * 
-	 * @param parent parent RTPSession
-	 * @param rtcpSocket parent RTPSession that started this
-	 * @param multicastGroup multicast group to bind the socket to
-	 */
-	protected RTCPSession(RTPSession parent, MulticastSocket rtcpSocket, InetAddress multicastGroup) {
-		mcGroup = multicastGroup;
-		this.rtcpSock = rtcpSocket;
-		rtpSession = parent;
-	}
-
-	/**
-	 * Starts the session, calculates delays and fires up the threads.
-	 *
-	 */
-	protected void start() {
-		//nextDelay = 2500 + rtpSession.random.nextInt(1000) - 500;
-		this.calculateDelay();
-		recvThrd = new RTCPReceiverThread(this, this.rtpSession);
-		senderThrd = new RTCPSenderThread(this, this.rtpSession);
-		recvThrd.start();
-		senderThrd.start();
-	}
-
-	/**
-	 * Send bye packets, handled by RTCP Sender thread
-	 *
-	 */
-	protected void sendByes() {
-		senderThrd.sendByes();
-	}
-	
-	/**
-	 * Calculate the delay before the next RTCP packet can be sent
-	 *
-	 */
-	protected void calculateDelay() {
-		switch(rtpSession.rtcpMode) {
-		case 0: calculateRegularDelay(); break;
-		default:
-			System.out.println("RTCPSession.calculateDelay() unknown .mode");
-		}
-	}
-
-	/**
-	 * Calculates a delay value in accordance with RFC 3550
-	 *
-	 */
-	protected void calculateRegularDelay() {
-		long curTime = System.currentTimeMillis();
-		
-		if(rtpSession.bandwidth != 0 && ! this.initial && rtpSession.partDb.ssrcTable.size() > 4) {
-			// RTPs mechanisms for RTCP scalability
-			int rand = rtpSession.random.nextInt(10000) - 5000; //between -500 and +500
-			double randDouble =  ((double) 1000 + rand)/1000.0;
-			
-			
-			Enumeration<Participant> enu = rtpSession.partDb.getParticipants();
-			while(enu.hasMoreElements()) {
-				Participant part = enu.nextElement();
-				if(part.lastRtpPkt > this.prevTime)
-					senderCount++;
-			}
-			
-			double bw;
-			if(rtpSession.rtcpBandwidth > -1) {
-				bw = rtpSession.rtcpBandwidth;
-			}else {
-				bw = rtpSession.bandwidth*0.05;
-			}
-			if(senderCount*2 > rtpSession.partDb.ssrcTable.size()) {
-				if(rtpSession.lastTimestamp > this.prevTime) {
-					//We're a sender
-					double numerator = ((double) this.avgPktSize)*((double) senderCount);
-					double denominator = 0.25*bw;
-					this.nextDelay = (int) Math.round((numerator/denominator)*randDouble);
-				} else {
-					//We're a receiver
-					double numerator = ((double) this.avgPktSize)*((double) rtpSession.partDb.ssrcTable.size());
-					double denominator = 0.75*bw;
-					this.nextDelay = (int) Math.round((numerator/denominator)*randDouble);
-				}
-			} else {
-				double numerator = ((double) this.avgPktSize)*((double) rtpSession.partDb.ssrcTable.size());;
-				double denominator = bw;
-				this.nextDelay = (int) Math.round(1000.0*(numerator/denominator)) * (1000 + rand);
-			}
-		} else {
-			// Not enough data to scale, use random values
-			int rand = rtpSession.random.nextInt(1000) - 500; //between -500 and +500
-			if(this.initial) {
-				// 2.5 to 3.5 seconds, randomly
-				this.nextDelay = 3000 + rand;
-				this.initial = false;
-			} else {
-				// 4.5 to 5.5 seconds, randomly
-				this.nextDelay = 5500 + rand;
-			}
-
-		}
-		
-		// preflight check
-		if(this.nextDelay < 1000) {
-			int rand = rtpSession.random.nextInt(1000) - 500; //between -500 and +500
-			System.out.println("RTCPSession.calculateDelay() nextDelay was too short (" 
-					+this.nextDelay+"ms), setting to "+(this.nextDelay = 2000 + rand));
-		}
-		this.prevTime = curTime;
-	}
-
-	/**
-	 * Update the average packet size
-	 * @param length of latest packet
-	 */
-	synchronized protected void updateAvgPacket(int length) {
-		double tempAvg = (double) this.avgPktSize;
-		tempAvg = (15*tempAvg + ((double) length))/16;
-		this.avgPktSize = (int) tempAvg;
-	}
-	
-	
-	/**
-	 * Adds an RTCP APP (application) packet to the queue
-	 *
-	 * @param targetSsrc the SSRC of the recipient
-	 * @param aPkt 
-	 */
-	synchronized protected void addToAppQueue(long targetSsrc, RtcpPktAPP aPkt) {
-		aPkt.time = System.currentTimeMillis();
-		
-		if(this.appQueue == null)
-			this.appQueue = new Hashtable<Long, LinkedList<RtcpPktAPP>>();
-		
-		LinkedList<RtcpPktAPP> ll = this.appQueue.get(targetSsrc);
-		if(ll == null) {
-			// No list, create and add
-			ll = new LinkedList<RtcpPktAPP>();
-			this.appQueue.put(targetSsrc, ll);
-		}
-		
-		ll.add(aPkt);
-	}
-	
-	
-	/**
-	 * Adds an RTCP APP (application) packet to the queue
-	 *
-	 * @param targetSsrc the SSRC of the recipient
-	 * @return array of RTCP Application packets 
-	 */
-	synchronized protected RtcpPktAPP[] getFromAppQueue(long targetSsrc) {		
-		if(this.appQueue == null)
-			return null;
-		
-		LinkedList<RtcpPktAPP> ll = this.appQueue.get(targetSsrc);
-		if(ll == null || ll.isEmpty()) {
-			return null;
-		} else {
-			RtcpPktAPP[] ret = new RtcpPktAPP[ll.size()];
-			ListIterator<RtcpPktAPP> li = ll.listIterator();
-			int i = 0;
-			while(li.hasNext()) {
-				ret[i] = li.next();
-				i++;
-			}
-			return ret;
-		}
-	}
-	
-	
-	/**
-	 * Cleans the TCP APP (application) packet queues of any packets that are
-	 * too old, defined as 60 seconds since insertion.
-	 * 
-	 * @param ssrc The SSRC of the user who has left, negative value -> general cleanup
-	 */
-	synchronized protected void cleanAppQueue(long ssrc) {
-		if(this.appQueue == null)
-			return;
-		
-		if(ssrc > 0) {
-			this.appQueue.remove(ssrc);
-		} else {
-			Enumeration<LinkedList<RtcpPktAPP>> enu = this.appQueue.elements();
-			long curTime = System.currentTimeMillis();
-
-
-			while(enu.hasMoreElements()) {
-				ListIterator<RtcpPktAPP> li = enu.nextElement().listIterator();
-				while(li.hasNext()) {
-					RtcpPkt aPkt = li.next();
-					//Remove after 60 seconds
-					if(curTime - aPkt.time > 60000) {
-						li.remove();
-					}
-				}
-			}	
-		}
-	}
-	
-	
-	
-	/**
-	 * Check the feedback queue for similar packets and adds
-	 * the new packet if it is not redundant
-	 * 
-	 * @param aPkt
-	 * @return 0 if the packet was added, 1 if it was dropped
-	 */
-	synchronized protected int addToFbQueue(long targetSsrc, RtcpPkt aPkt) {
-		if(this.fbQueue == null)
-			this.fbQueue = new Hashtable<Long, LinkedList<RtcpPkt>>();
-		
-		LinkedList<RtcpPkt> ll = this.fbQueue.get(targetSsrc);
-		if(ll == null) {
-			// No list, create and add
-			ll = new LinkedList<RtcpPkt>();
-			ll.add(aPkt);
-			this.fbQueue.put(targetSsrc, ll);
-		} else {
-			// Check for matching packets, else add to end
-			ListIterator<RtcpPkt> li = ll.listIterator();
-			while(li.hasNext()) {
-				RtcpPkt tmp = li.next();
-				if(equivalent(tmp, aPkt))
-					return -1;
-			}
-			ll.addLast(aPkt);
-		}
-		return 0;
-	}
-		
-	/**
-	 * Checks whether there are ny feedback packets waiting
-	 * to be sent.
-	 * 
-	 * @param ssrc of the participant we are notifying
-	 * @return all relevant feedback packets, or null
-	 */
-	synchronized protected RtcpPkt[] getFromFbQueue(long ssrc) {
-		if(this.fbQueue == null)
-			return null;
-		
-		LinkedList<RtcpPkt> ll = this.fbQueue.get(ssrc);
-		
-		if(ll == null)
-			return null;
-		
-		ListIterator<RtcpPkt> li = ll.listIterator();
-		if(li.hasNext()) {
-			long curTime = System.currentTimeMillis();
-			long maxDelay = curTime - rtpSession.fbMaxDelay;
-			long keepDelay =  curTime - 2000;
-			int count = 0;
-			
-			//TODO below the indeces should be collected instead of looping twice
-			
-			// Clean out what we dont want and count what we want
-			while(li.hasNext()) {
-				RtcpPkt aPkt = li.next();
-				if(aPkt.received) {
-					//This is a packet received, we keep these for
-					// 2000ms to avoid redundant feedback
-					if(aPkt.time < keepDelay)
-						li.remove();
-				} else {
-					//This is a packet we havent sent yet
-					if(aPkt.time < maxDelay) {
-						li.remove();
-					} else {
-						count++;
-					}
-				}
-			}
-			
-			// Gather what we want to return
-			if(count != 0) {
-				li = ll.listIterator();
-				RtcpPkt[] ret = new RtcpPkt[count];
-		
-				while(count > 0) {
-					RtcpPkt aPkt = li.next();
-					if(! aPkt.received) {
-						ret[ret.length - count] = aPkt; 
-						count--;
-					}
-				}
-				return ret;
-			}
-		}
-		
-		return null;
-	}
-	
-	/**
-	 * Cleans the feeback queue of any packets that have expired,
-	 * ie feedback packet that are no longer relevant.
-	 * 
-	 * @param ssrc The SSRC of the user who has left, negative value -> general cleanup
-	 */
-	synchronized protected void cleanFbQueue(long ssrc) {
-		if(this.fbQueue == null)
-			return;
-		
-		if(ssrc > 0) {
-			this.fbQueue.remove(ssrc);
-		} else { 
-			Enumeration<LinkedList<RtcpPkt>> enu = this.fbQueue.elements();
-			long curTime = System.currentTimeMillis();
-			long maxDelay = curTime - rtpSession.fbMaxDelay;
-			long keepDelay =  curTime - 2000;
-
-			while(enu.hasMoreElements()) {
-				ListIterator<RtcpPkt> li = enu.nextElement().listIterator();
-				while(li.hasNext()) {
-					RtcpPkt aPkt = li.next();
-					if(aPkt.received) {
-						//This is a packet received, we keep these for
-						// 2000ms to avoid redundant feedback
-						if(aPkt.time < keepDelay)
-							li.remove();
-					} else {
-						//This is a packet we havent sent yet
-						if(aPkt.time < maxDelay)
-							li.remove();
-					}
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Check whether the conditions are satisfied to send a feedbkac packet immediately.
-	 * 
-	 * @return true if they are, false otherwise
-	 */
-	protected boolean fbSendImmediately() {
-		if(rtpSession.partDb.ssrcTable.size() > this.rtpSession.fbEarlyThreshold 
-				&& rtpSession.partDb.receivers.size() > this.rtpSession.fbEarlyThreshold)
-			return false;
-		
-		return true;
-	}
-	
-	
-	/**
-	 * Check whether the conditions are satisfied to send a feedbkac packet immediately.
-	 * 
-	 * @return true if they are, false otherwise
-	 */
-	protected boolean fbSendEarly() {
-		if(rtpSession.partDb.ssrcTable.size() > this.rtpSession.fbRegularThreshold 
-				&& rtpSession.partDb.receivers.size() > this.rtpSession.fbRegularThreshold)
-			return false;
-		
-		return true;
-	}
-	
-	/**
-	 * Wake the sender thread because of this ssrc
-	 * 
-	 * @param ssrc that has feedback waiting.
-	 */
-	protected void wakeSenderThread(long ssrc) {
-		this.fbWaiting = ssrc;
-		this.senderThrd.interrupt();
-		
-		// Give it a chance to catch up
-		try { Thread.sleep(0,1); } catch (Exception e){ };
-	}
-	
-	/**
-	 * Compares two packets to check whether they are equivalent feedback messages,
-	 * to avoid sending the same feedback to a host twice.
-	 * 
-	 * Expect false negatives, but not false positives.
-	 * 
-	 * @param one packet
-	 * @param two packet
-	 * @return true if they are equivalent, false otherwise 
-	 */
-	private boolean equivalent(RtcpPkt one, RtcpPkt two) {
-		// Cheap checks
-		if(one.packetType != two.packetType)
-			return false;
-		
-		if(one.itemCount != two.itemCount)
-			return false;
-		
-		if(one.packetType == 205) {
-			// RTP Feedback, i.e. a NACK
-			RtcpPktRTPFB pktone = (RtcpPktRTPFB) one;
-			RtcpPktRTPFB pkttwo = (RtcpPktRTPFB) two;
-
-			if(pktone.ssrcMediaSource != pkttwo.ssrcMediaSource)
-				return false;
-			
-			if(Arrays.equals(pktone.BLP,pkttwo.BLP) 
-					&& Arrays.equals(pktone.BLP,pkttwo.BLP))
-				return true;
-			
-			return true;
-		} else if(one.packetType == 206) {
-			RtcpPktPSFB pktone = (RtcpPktPSFB) one;
-			RtcpPktPSFB pkttwo = (RtcpPktPSFB) two;
-
-			if(pktone.ssrcMediaSource != pkttwo.ssrcMediaSource)
-				return false;
-			
-			switch(one.itemCount) {
-			case 1: // Picture Loss Indication 
-				return true;
-				
-			case 2: // Slice Loss Indication
-				// This will not work if the slice loss indicators are in different order
-				if(pktone.sliFirst.length == pkttwo.sliFirst.length
-						&& Arrays.equals(pktone.sliFirst, pkttwo.sliFirst) 
-						&& Arrays.equals(pktone.sliNumber, pkttwo.sliNumber)
-						&& Arrays.equals(pktone.sliPictureId, pkttwo.sliPictureId))
-					return true;
-				break;
-			case 3: // Reference Picture Selection Indication 
-				if(Arrays.equals(pktone.rpsiBitString, pkttwo.rpsiBitString))
-					return true;
-				break;
-			case 15: // Application Layer Feedback Messages
-				// This will not work if the padding scheme is different
-				if(pktone.sliFirst.length == pkttwo.sliFirst.length
-						&& Arrays.equals(pktone.alfBitString, pkttwo.alfBitString))
-					return true;
-				break;
-			default:
-				
-			}
-			return true;
-		} else {
-			System.out.println("!!!! RTCPSession.equivalentPackets() encountered unexpected packet type!");
-		}
-		return false;
-	}
-}
-
--- a/src/jlibrtp/RTPAppIntf.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-package jlibrtp;
-
-
-/**
- * This is the callback interface for RTP packets.
- * 
- * It is mandatory, but you can inore the data if you like.
- * 
- * @author Arne Kepp
- */
-public interface RTPAppIntf {
-	
-	/**
-	 * The callback method through which the application will receive
-	 * data from jlibrtp. These calls are synchronous, so you will not
-	 * receive any new packets until this call returns.
-	 * 
-	 * @param frame the frame containing the data
-	 * @param participant the participant from which the data came
-	 */
-	public void receiveData(DataFrame frame, Participant participant);
-	
-	
-	/**
-	 * The callback method through which the application will receive
-	 * notifications about user updates, additions and byes.
-	 *  Types:
-	 *  	1 - Bye
-	 *  	2 - New through RTP, check .getRtpSendSock()
-	 *  	3 - New through RTCP, check .getRtcpSendSock()
-	 * 		4 - SDES packet received, check the getCname() etc methods
-	 *      5 - Matched SSRC to ip-address provided by application
-	 * 
-	 * @param type the type of event
-	 * @param participant the participants in question
-	 */
-	public void userEvent(int type, Participant[] participant);
-	
-	/**
-	 * The callback method through which the application can specify
-	 * the number of packets that make up a frame for a given payload type.
-	 * 
-	 * A negative value denotes frames of variable length, so jlibrtp
-	 * will return whatever it has at the time.
-	 * 
-	 * In most applications, this function can simply return 1.
-	 * 
-	 * This should be implemented as something fast, such as an
-	 * integer array with the indeces being the payload type.
-	 * 
-	 * @param payloadType the payload type specified in the RTP packet
-	 * @return the number of packets that make up a frame
-	 */
-	public int frameSize(int payloadType);
-}
--- a/src/jlibrtp/RTPReceiverThread.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.InetSocketAddress;
-
-/**
- * The RTP receiver thread waits on the designated UDP socket for new packets.
- * 
- * Once one arrives, it is parsed and tested. We also check the ip-address of the sender. 
- * If accepted, the packet is added onto the packet buffer of the participant.
- * 
- * A separate thread moves the packet from the packet buffer to the application.
- * 
- * @author Arne Kepp
- */
-public class RTPReceiverThread extends Thread {
-	/** Parent RTP Session */
-	RTPSession rtpSession = null;
-
-	RTPReceiverThread(RTPSession session) {
-		rtpSession = session;
-		if(RTPSession.rtpDebugLevel > 1) {
-			System.out.println("<-> RTPReceiverThread created");
-		} 
-	}
-
-	public void run() {
-		if(RTPSession.rtpDebugLevel > 1) {
-			if(rtpSession.mcSession) {
-				System.out.println("-> RTPReceiverThread.run() starting on MC " + rtpSession.rtpMCSock.getLocalPort() );
-			} else {
-				System.out.println("-> RTPReceiverThread.run() starting on " + rtpSession.rtpSock.getLocalPort() );
-			}
-		}
-
-		while(!rtpSession.endSession) {
-			if(RTPSession.rtpDebugLevel > 6) {
-				if(rtpSession.mcSession) {
-					System.out.println("-> RTPReceiverThread.run() waiting for MC packet on " + rtpSession.rtpMCSock.getLocalPort() );
-				} else {
-					System.out.println("-> RTPReceiverThread.run() waiting for packet on " + rtpSession.rtpSock.getLocalPort() );
-				}
-			}
-
-			// Prepare a packet
-			byte[] rawPkt = new byte[1500];
-			DatagramPacket packet = new DatagramPacket(rawPkt, rawPkt.length);
-			// Wait for it to arrive
-			if(! rtpSession.mcSession) {
-				//Unicast
-				try {
-					rtpSession.rtpSock.receive(packet);
-				} catch (IOException e) {
-					if(!rtpSession.endSession) {
-						e.printStackTrace();
-					} else {
-						continue;
-					}
-				}
-			} else {
-				//Multicast 
-				try {
-					rtpSession.rtpMCSock.receive(packet);
-				} catch (IOException e) {
-					if(!rtpSession.endSession) {
-						e.printStackTrace();
-					} else {
-						continue;
-					}
-				}
-			}
-
-			// Parse the received RTP (?) packet
-			RtpPkt pkt = new RtpPkt(rawPkt, packet.getLength());
-
-			// Check whether it was valid.
-			if(pkt == null) {
-				System.out.println("Received invalid RTP packet. Ignoring");
-				continue;
-			}
-			
-			long pktSsrc = pkt.getSsrc();
-			
-			// Check for loops and SSRC collisions
-			if( rtpSession.ssrc == pktSsrc )
-				rtpSession.resolveSsrcConflict();
-			
-			long[] csrcArray = pkt.getCsrcArray();
-			if( csrcArray != null) {
-				for(int i=0; i< csrcArray.length; i++) {
-					if(csrcArray[i] == rtpSession.ssrc);
-						rtpSession.resolveSsrcConflict();
-				}
-			}
-			
-			if(RTPSession.rtpDebugLevel > 17) {
-				System.out.println("-> RTPReceiverThread.run() rcvd packet, seqNum " + pktSsrc );
-				if(RTPSession.rtpDebugLevel > 10) {
-					String str = new String(pkt.getPayload());
-					System.out.println("-> RTPReceiverThread.run() payload is " + str );
-				}
-			}
-			
-			//Find the participant in the database based on SSRC
-			Participant part = rtpSession.partDb.getParticipant(pktSsrc);
-
-			if(part == null) {
-				InetSocketAddress nullSocket = null;
-				part = new Participant((InetSocketAddress) packet.getSocketAddress(), nullSocket, pkt.getSsrc());
-				part.unexpected = true;
-				rtpSession.partDb.addParticipant(1,part);
-			}
-
-			// Do checks on whether the datagram came from the expected source for that SSRC.
-			if(part.rtpAddress == null || packet.getAddress().equals(part.rtpAddress.getAddress())) {
-				PktBuffer pktBuffer = part.pktBuffer;
-
-				if(pktBuffer != null) {
-					//A buffer already exists, append to it
-					pktBuffer.addPkt(pkt);
-				} else {
-					// Create a new packet/frame buffer
-					pktBuffer = new PktBuffer(this.rtpSession, part,pkt);
-					part.pktBuffer = pktBuffer;
-				}
-			} else {
-				System.out.println("RTPReceiverThread: Got an unexpected packet from " + pkt.getSsrc() 
-						+ " the sending ip-address was " + packet.getAddress().toString() 
-						+ ", we expected from " + part.rtpAddress.toString());
-			}
-
-			// Statistics for receiver report.
-			part.updateRRStats(packet.getLength(), pkt);
-			// Upate liveness
-			part.lastRtpPkt = System.currentTimeMillis();
-
-			if(RTPSession.rtpDebugLevel > 5) {
-				System.out.println("<-> RTPReceiverThread signalling pktBufDataReady");
-			}
-			
-			// Signal the thread that pushes data to application
-			rtpSession.pktBufLock.lock();
-			try { rtpSession.pktBufDataReady.signalAll(); } finally {
-				rtpSession.pktBufLock.unlock();
-			}
-
-		}
-	}
-
-}
--- a/src/jlibrtp/RTPSession.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1053 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.DatagramSocket;
-import java.net.MulticastSocket;
-import java.net.DatagramPacket;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.Iterator;
-import java.util.concurrent.locks.*;
-import java.util.Random;
-import java.util.Enumeration;
-/**
- * The RTPSession object is the core of jlibrtp. 
- * 
- * One should be instantiated for every communication channel, i.e. if you send voice and video, you should create one for each.
- * 
- * The instance holds a participant database, as well as other information about the session. When the application registers with the session, the necessary threads for receiving and processing RTP packets are spawned.
- * 
- * RTP Packets are sent synchronously, all other operations are asynchronous.
- * 
- * @author Arne Kepp
- */
-public class RTPSession {
-	 /**
-	  * The debug level is final to avoid compilation of if-statements.</br>
-	  * 0 provides no debugging information, 20 provides everything </br>
-	  * Debug output is written to System.out</br>
-	  * Debug level for RTP related things.
-	  */
-	 final static public int rtpDebugLevel = 0;
-	 /**
-	  * The debug level is final to avoid compilation of if-statements.</br>
-	  * 0 provides no debugging information, 20 provides everything </br>
-	  * Debug output is written to System.out</br>
-	  * Debug level for RTCP related things.
-	  */
-	 final static public int rtcpDebugLevel = 0;
-	 
-	 /** RTP unicast socket */
-	 protected DatagramSocket rtpSock = null;
-	 /** RTP multicast socket */
-	 protected MulticastSocket rtpMCSock = null;
-	 /** RTP multicast group */
-	 protected InetAddress mcGroup = null;
-	 
-	 // Internal state
-	 /** Whether this session is a multicast session or not */
-	 protected boolean mcSession = false;
-	 /** Current payload type, can be changed by application */
-	 protected int payloadType = 0;
-	 /** SSRC of this session */
-	 protected long ssrc;
-	 /** The last timestamp when we sent something */
-	 protected long lastTimestamp = 0;
-	 /** Current sequence number */
-	 protected int seqNum = 0;
-	 /** Number of packets sent by this session */
-	 protected int sentPktCount = 0;
-	 /** Number of octets sent by this session */
-	 protected int sentOctetCount = 0;
-	 
-	 /** The random seed */
-	 protected Random random = null;
-	 
-	 /** Session bandwidth in BYTES per second */
-	 protected int bandwidth = 8000;
-	 
-	 /** By default we do not return packets from strangers in unicast mode */
-	 protected boolean naiveReception = false;
-	 
-	 /** Should the library attempt frame reconstruction? */
-	 protected boolean frameReconstruction = true;
-	 
-	 /** Maximum number of packets used for reordering */
-	 protected int pktBufBehavior = 3;
-	 
-	 /** Participant database */
-	 protected ParticipantDatabase partDb = new ParticipantDatabase(this); 
-	 /** Handle to application interface for RTP */
-	 protected RTPAppIntf appIntf = null;
-	 /** Handle to application interface for RTCP (optional) */
-	 protected RTCPAppIntf rtcpAppIntf = null;
-	 /** Handle to application interface for AVPF, RFC 4585 (optional) */
-	 protected RTCPAVPFIntf rtcpAVPFIntf = null;
-	 /** Handle to application interface for debugging */
-	 protected DebugAppIntf debugAppIntf = null;
-	 
-	 /** The RTCP session associated with this RTP Session */
-	 protected RTCPSession rtcpSession = null;
-	 /** The thread for receiving RTP packets */
-	 protected RTPReceiverThread recvThrd = null;
-	 /** The thread for invoking callbacks for RTP packets */
-	 protected AppCallerThread appCallerThrd = null;
-	 
-	 /** Lock to protect the packet buffers */
-	 final protected Lock pktBufLock = new ReentrantLock();
-	 /** Condition variable, to tell the  */
-	 final protected Condition pktBufDataReady = pktBufLock.newCondition();
-	 
-	 /** Enough is enough, set to true when you want to quit. */
-	 protected boolean endSession = false;
-	 /** Only one registered application, please */
-	 protected boolean registered = false;
-	 /** We're busy resolving a SSRC conflict, please try again later */
-	 protected boolean conflict = false;
-	 /** Number of conflicts observed, exessive number suggests loop in network */
-	 protected int conflictCount = 0;
-	 
-	 /** SDES CNAME */
-	 protected String cname = null;
-	 /** SDES The participant's real name */
-	 public String name = null;
-	 /** SDES The participant's email */
-	 public String email = null;
-	 /** SDES The participant's phone number */
-	 public String phone = null;
-	 /** SDES The participant's location*/
-	 public String loc = null;
-	 /** SDES The tool the participants is using */
-	 public String tool = null;
-	 /** SDES A note */
-	 public String note = null;
-	 /** SDES A priv string, loosely defined */
-	 public String priv = null;
-		
-	 // RFC 4585 stuff. This should live on RTCPSession, but we need to have this
-	 // infromation ready by the time the RTCP Session starts
-	 // 0 = RFC 3550 , -1 = ACK , 1 = Immediate feedback, 2 = Early RTCP,  
-	 protected int rtcpMode = 0;
-	 protected int fbEarlyThreshold = -1;		// group size, immediate -> early transition point
-	 protected int fbRegularThreshold = -1;	// group size, early -> regular transition point
-	 protected int minInterval = 5000;		// minimum interval
-	 protected int fbMaxDelay = 1000;			// how long the information is useful
-	 // RTCP bandwidth
-	 protected int rtcpBandwidth = -1;
-	 
-	 
-	 /**
-	  * Returns an instance of a <b>unicast</b> RTP session. 
-	  * Following this you should adjust any settings and then register your application.
-	  * 
-	  * The sockets should have external ip addresses, else your CNAME automatically
-	  * generated CNAMe will be bad.
-	  * 
-	  * @param	rtpSocket UDP socket to receive RTP communication on
-	  * @param	rtcpSocket UDP socket to receive RTCP communication on, null if none.
-	  */
-	 public RTPSession(DatagramSocket rtpSocket, DatagramSocket rtcpSocket) {
-		 mcSession = false;
-		 rtpSock = rtpSocket;
-		 this.generateCNAME();
-		 this.generateSsrc();
-		 this.rtcpSession = new RTCPSession(this,rtcpSocket);
-		 
-		 // The sockets are not always imediately available?
-		 try { Thread.sleep(1); } catch (InterruptedException e) { System.out.println("RTPSession sleep failed"); }
-	 }
-	 
-	 /**
-	  * Returns an instance of a <b>multicast</b> RTP session. 
-	  * Following this you should register your application.
-	  * 
-	  * The sockets should have external ip addresses, else your CNAME automatically
-	  * generated CNAMe will be bad.
-	  * 
-	  * @param	rtpSock a multicast socket to receive RTP communication on
-	  * @param	rtcpSock a multicast socket to receive RTP communication on
-	  * @param	multicastGroup the multicast group that we want to communicate with.
-	  */
-	 public RTPSession(MulticastSocket rtpSock, MulticastSocket rtcpSock, InetAddress multicastGroup) throws Exception {
-		 mcSession = true;
-		 rtpMCSock =rtpSock;
-		 mcGroup = multicastGroup;
-		 rtpMCSock.joinGroup(mcGroup);
-		 rtcpSock.joinGroup(mcGroup);
-		 this.generateCNAME();
-		 this.generateSsrc();
-		 this.rtcpSession = new RTCPSession(this,rtcpSock,mcGroup);
-		 
-		 // The sockets are not always imediately available?
-		 try { Thread.sleep(1); } catch (InterruptedException e) { System.out.println("RTPSession sleep failed"); }
-	 }
-	 
-	 /**
-	  * Registers an application (RTPAppIntf) with the RTP session.
-	  * The session will call receiveData() on the supplied instance whenever data has been received.
-	  * 
-	  * Following this you should set the payload type and add participants to the session.
-	  * 
-	  * @param	rtpApp an object that implements the RTPAppIntf-interface
-	  * @param	rtcpApp an object that implements the RTCPAppIntf-interface (optional)
-	  * @return	-1 if this RTPSession-instance already has an application registered.
-	  */
-	 public int RTPSessionRegister(RTPAppIntf rtpApp, RTCPAppIntf rtcpApp, DebugAppIntf debugApp) {
-		if(registered) {
-			System.out.println("RTPSessionRegister(): Can\'t register another application!");
-			return -1;
-		} else {
-			registered = true;
-			generateSeqNum();
-			if(RTPSession.rtpDebugLevel > 0) {
-				System.out.println("-> RTPSessionRegister");
-			}  
-			this.appIntf = rtpApp;
-			this.rtcpAppIntf = rtcpApp;
-			this.debugAppIntf = debugApp;
-			
-			recvThrd = new RTPReceiverThread(this);
-			appCallerThrd = new AppCallerThread(this, rtpApp);
-			recvThrd.start();
-		 	appCallerThrd.start();
-		 	rtcpSession.start();
-		 	return 0;
-		}
-	}
-	
-	 /**
-	  * Send data to all participants registered as receivers, using the current timeStamp,
-	  * dynamic sequence number and the current payload type specified for the session.
-	  * 
-	  * @param buf A buffer of bytes, less than 1496 bytes
-	  * @return	null if there was a problem, {RTP Timestamp, Sequence number} otherwise
-	  */
-	 public long[] sendData(byte[] buf) {
-		 byte[][] tmp = {buf}; 
-		 long[][] ret = this.sendData(tmp, null, null, -1, null);
-		 
-		 if(ret != null)
-			 return ret[0];
-		 
-		 return null;
-	 }
-	 
-	 /**
-	  * Send data to all participants registered as receivers, using the specified timeStamp,
-	  * sequence number and the current payload type specified for the session.
-	  * 
-	  * @param buf A buffer of bytes, less than 1496 bytes
-	  * @param rtpTimestamp the RTP timestamp to be used in the packet
-	  * @param seqNum the sequence number to be used in the packet
-	  * @return null if there was a problem, {RTP Timestamp, Sequence number} otherwise
-	  */
-	 public long[] sendData(byte[] buf, long rtpTimestamp, long seqNum) {
-		 byte[][] tmp = {buf};
-		 long[][] ret = this.sendData(tmp, null, null, -1, null);
-		 
-		 if(ret != null)
-			 return ret[0];
-		 
-		 return null;
-	 }
-	 
-	 /**
-	  * Send data to all participants registered as receivers, using the current timeStamp and
-	  * payload type. The RTP timestamp will be the same for all the packets.
-	  * 
-	  * @param buffers A buffer of bytes, should not bed padded and less than 1500 bytes on most networks.
-	  * @param csrcArray an array with the SSRCs of contributing sources
-	  * @param markers An array indicating what packets should be marked. Rarely anything but the first one
-	  * @param rtpTimestamp The RTP timestamp to be applied to all packets
-	  * @param seqNumbers An array with the sequence number associated with each byte[]
-	  * @return	null if there was a problem sending the packets, 2-dim array with {RTP Timestamp, Sequence number}
-	  */
-	 public long[][] sendData(byte[][] buffers, long[] csrcArray, boolean[] markers, long rtpTimestamp, long[] seqNumbers) {
-		 if(RTPSession.rtpDebugLevel > 5) {
-			 System.out.println("-> RTPSession.sendData(byte[])");
-		 }
-
-		 // Same RTP timestamp for all
-		 if(rtpTimestamp < 0)
-			 rtpTimestamp = System.currentTimeMillis();
-		 
-		 // Return values
-		 long[][] ret = new long[buffers.length][2];
-
-		 for(int i=0; i<buffers.length; i++) {
-			 byte[] buf = buffers[i];
-			 
-			 boolean marker = false;
-			 if(markers != null)
-				  marker = markers[i];
-			 
-			 if(buf.length > 1500) {
-				 System.out.println("RTPSession.sendData() called with buffer exceeding 1500 bytes ("+buf.length+")");
-			 }
-
-			 // Get the return values
-			 ret[i][0] = rtpTimestamp;
-			 if(seqNumbers == null) {
-				 ret[i][1] = getNextSeqNum();
-			 } else {
-				 ret[i][1] = seqNumbers[i];
-			 }
-			 // Create a new RTP Packet
-			 RtpPkt pkt = new RtpPkt(rtpTimestamp,this.ssrc,(int) ret[i][1],this.payloadType,buf);
-
-			 if(csrcArray != null)
-				 pkt.setCsrcs(csrcArray);
-
-			 pkt.setMarked(marker);
-
-			 // Creates a raw packet
-			 byte[] pktBytes = pkt.encode();
-			 
-			 //System.out.println(Integer.toString(StaticProcs.bytesToUIntInt(pktBytes, 2)));
-
-			 // Pre-flight check, are resolving an SSRC conflict?
-			 if(this.conflict) {
-				 System.out.println("RTPSession.sendData() called while trying to resolve conflict.");
-				 return null;
-			 }
-
-
-			 if(this.mcSession) {
-				 DatagramPacket packet = null;
-
-
-				 try {
-					 packet = new DatagramPacket(pktBytes,pktBytes.length,this.mcGroup,this.rtpMCSock.getPort());
-				 } catch (Exception e) {
-					 System.out.println("RTPSession.sendData() packet creation failed.");
-					 e.printStackTrace();
-					 return null;
-				 }
-
-				 try {
-					 rtpMCSock.send(packet);
-					 //Debug
-					 if(this.debugAppIntf != null) {
-						 this.debugAppIntf.packetSent(1, (InetSocketAddress) packet.getSocketAddress(), 
-								 new String("Sent multicast RTP packet of size " + packet.getLength() + 
-										 " to " + packet.getSocketAddress().toString() + " via " 
-										 + rtpMCSock.getLocalSocketAddress().toString()));
-					 }
-				 } catch (Exception e) {
-					 System.out.println("RTPSession.sendData() multicast failed.");
-					 e.printStackTrace();
-					 return null;
-				 }		
-
-			 } else {
-				 // Loop over recipients
-				 Iterator<Participant> iter = partDb.getUnicastReceivers();
-				 while(iter.hasNext()) {			
-					 InetSocketAddress receiver = iter.next().rtpAddress;
-					 DatagramPacket packet = null;
-
-					 if(RTPSession.rtpDebugLevel > 15) {
-						 System.out.println("   Sending to " + receiver.toString());
-					 }
-
-					 try {
-						 packet = new DatagramPacket(pktBytes,pktBytes.length,receiver);
-					 } catch (Exception e) {
-						 System.out.println("RTPSession.sendData() packet creation failed.");
-						 e.printStackTrace();
-						 return null;
-					 }
-
-					 //Actually send the packet
-					 try {
-						 rtpSock.send(packet);
-						 //Debug
-						 if(this.debugAppIntf != null) {
-							 this.debugAppIntf.packetSent(0, (InetSocketAddress) packet.getSocketAddress(), 
-									 new String("Sent unicast RTP packet of size " + packet.getLength() + 
-											 " to " + packet.getSocketAddress().toString() + " via " 
-											 + rtpSock.getLocalSocketAddress().toString()));
-						 }
-					 } catch (Exception e) {
-						 System.out.println("RTPSession.sendData() unicast failed.");
-						 e.printStackTrace();
-						 return null;
-					 }
-				 }
-			 }
-
-			 //Update our stats
-			 this.sentPktCount++;
-			 this.sentOctetCount++;
-
-			 if(RTPSession.rtpDebugLevel > 5) {
-				 System.out.println("<- RTPSession.sendData(byte[]) " + pkt.getSeqNumber());
-			 }  
-		 }
-
-		 return ret;
-	 }
-	 
-	 /**
-	  * Send RTCP App packet to receiver specified by ssrc
-	  * 
-	  * 
-	  * 
-	  * Return values:
-	  *  0 okay
-	  * -1 no RTCP session established
-	  * -2 name is not byte[4];
-	  * -3 data is not byte[x], where x = 4*y for syme y
-	  * -4 type is not a 5 bit unsigned integer
-	  * 
-	  * Note that a return value of 0 does not guarantee delivery.
-	  * The participant must also exist in the participant database,
-	  * otherwise the message will eventually be deleted.
-	  * 
-	  * @param ssrc of the participant you want to reach
-	  * @param type the RTCP App packet subtype, default 0
-	  * @param name the ASCII (in byte[4]) representation
-	  * @param data the data itself 
-	  * @return 0 if okay, negative value otherwise (see above)
-	  */
-	
-	 public int sendRTCPAppPacket(long ssrc, int type, byte[] name, byte[] data) {
-		 if(this.rtcpSession == null)
-			 return -1;
-		 
-		 if(name.length != 4)
-			 return -2;
-		 
-		 if(data.length % 4 != 0)
-			 return -3;
-		 
-		 if(type > 63 || type < 0 )
-			 return -4;
-		
-		RtcpPktAPP pkt = new RtcpPktAPP(ssrc, type, name, data);
-		this.rtcpSession.addToAppQueue(ssrc, pkt);
-		
-		return 0;
-	 }
-	 /**
-	  * Add a participant object to the participant database.
-	  * 
-	  * If packets have already been received from this user, we will try to update the automatically inserted participant with the information provided here.
-	  *
-	  * @param p A participant.
-	  */
-	public int addParticipant(Participant p) {
-		//For now we make all participants added this way persistent
-		p.unexpected = false;
-		return this.partDb.addParticipant(0, p);
-	}
-	
-	 /**
-	  * Remove a participant from the database. All buffered packets will be destroyed.
-	  *
-	  * @param p A participant.
-	  */
-	 public void removeParticipant(Participant p) {
-		partDb.removeParticipant(p);
-	 }
-	 
-	 public Iterator<Participant> getUnicastReceivers() {
-		 return partDb.getUnicastReceivers();
-	 }
-	 
-	 public Enumeration<Participant> getParticipants() {
-		 return partDb.getParticipants();
-	 }
-	 
-	 /**
-	  * End the RTP Session. This will halt all threads and send bye-messages to other participants.
-	  * 
-	  * RTCP related threads may require several seconds to wake up and terminate.
-	  */
-	public void endSession() {
-		this.endSession = true;
-		
-		// No more RTP packets, please
-		if(this.mcSession) {
-			this.rtpMCSock.close();
-		} else {
-			this.rtpSock.close();
-		}
-		
-		// Signal the thread that pushes data to application
-		this.pktBufLock.lock();
-		try { this.pktBufDataReady.signalAll(); } finally {
-			this.pktBufLock.unlock();
-		}
-		// Interrupt what may be sleeping
-		this.rtcpSession.senderThrd.interrupt();
-		
-		// Give things a chance to cool down.
-		try { Thread.sleep(50); } catch (Exception e){ };
-		
-		this.appCallerThrd.interrupt();
-
-		// Give things a chance to cool down.
-		try { Thread.sleep(50); } catch (Exception e){ };
-		
-		if(this.rtcpSession != null) {		
-			// No more RTP packets, please
-			if(this.mcSession) {
-				this.rtcpSession.rtcpMCSock.close();
-			} else {
-				this.rtcpSession.rtcpSock.close();
-			}
-		}
-	}
-
-	
-	 /**
-	  * Check whether this session is ending.
-	  * 
-	  * @return true if session and associated threads are terminating.
-	  */
-	boolean isEnding() {
-		return this.endSession;
-	}
-
-	/**
-	 * Overrides CNAME, used for outgoing RTCP packets.
-	 * 
-	 * @param cname a string, e.g. username@hostname. Must be unique for session.
-	 */
-	public void CNAME(String cname) {
-		this.cname = cname;
-	}
-	
-	/**
-	 * Get the current CNAME, used for outgoing SDES packets
-	 */
-	public String CNAME() {
-		return this.cname;
-	}
-	
-	public long getSsrc() {
-		return this.ssrc;
-	}
-	
-	private void generateCNAME() {
-		String hostname;
-		
-		if(this.mcSession) {
-			hostname = this.rtpMCSock.getLocalAddress().getCanonicalHostName();
-		} else {
-			hostname = this.rtpSock.getLocalAddress().getCanonicalHostName();
-		}
-		
-		//if(hostname.equals("0.0.0.0") && System.getenv("HOSTNAME") != null) {
-		//	hostname = System.getenv("HOSTNAME");
-		//}
-		
-		cname = System.getProperty("user.name") + "@" + hostname;
-	}
-	
-	/**
-	 * Change the RTP socket of the session. 
-	 * Peers must be notified through SIP or other signalling protocol.
-	 * Only valid if this is a unicast session to begin with.
-	 * 
-	 * @param newSock integer for new port number, check it is free first.
-	 */
-	public int updateRTPSock(DatagramSocket newSock) {
-		if(!mcSession) {
-			 rtpSock = newSock;
-			 return 0;
-		} else {
-			System.out.println("Can't switch from multicast to unicast.");
-			return -1;
-		}
-	}
-	
-	/**
-	 * Change the RTCP socket of the session. 
-	 * Peers must be notified through SIP or other signalling protocol.
-	 * Only valid if this is a unicast session to begin with.
-	 * 
-	 * @param newSock the new unicast socket for RTP communication.
-	 */
-	public int updateRTCPSock(DatagramSocket newSock) {
-		if(!mcSession) {
-			this.rtcpSession.rtcpSock = newSock;
-			return 0;
-		} else {
-			System.out.println("Can't switch from multicast to unicast.");
-			return -1;
-		}
-	}
-	
-	/**
-	 * Change the RTP multicast socket of the session. 
-	 * Peers must be notified through SIP or other signalling protocol.
-	 * Only valid if this is a multicast session to begin with.
-	 * 
-	 * @param newSock the new multicast socket for RTP communication.
-	 */
-	public int updateRTPSock(MulticastSocket newSock) {
-		if(mcSession) {
-			 this.rtpMCSock = newSock;
-			 return 0;
-		} else {
-			System.out.println("Can't switch from unicast to multicast.");
-			return -1;
-		}
-	}
-	
-	/**
-	 * Change the RTCP multicast socket of the session. 
-	 * Peers must be notified through SIP or other signalling protocol.
-	 * Only valid if this is a multicast session to begin with.
-	 * 
-	 * @param newSock the new multicast socket for RTCP communication.
-	 */
-	public int updateRTCPSock(MulticastSocket newSock) {
-		if(mcSession) {
-			this.rtcpSession.rtcpMCSock = newSock;
-			return 0;
-		} else {
-			System.out.println("Can't switch from unicast to multicast.");
-			return -1;
-		}
-	}
-	
-	/**
-	 * Update the payload type used for the session. It is represented as a 7 bit integer, whose meaning must be negotiated elsewhere (see IETF RFCs <a href="http://www.ietf.org/rfc/rfc3550.txt">3550</a> and <a href="http://www.ietf.org/rfc/rfc3550.txt">3551</a>)
-	 * 
-	 * @param payloadT an integer representing the payload type of any subsequent packets that are sent.
-	 */
-	public int payloadType(int payloadT) {
-		if(payloadT > 128 || payloadT < 0) {
-			return -1;
-		} else {
-			this.payloadType = payloadT;
-			return this.payloadType;
-		}
-	}
-	
-	/**
-	 * Get the payload type that is currently used for outgoing RTP packets.
-	 * 
-	 * @return payload type as integer
-	 */
-	public int payloadType() {
-		return this.payloadType;
-	}
-	
-	/**
-	 * Should packets from unknown participants be returned to the application? This can be dangerous.
-	 * 
-	 * @param doAccept packets from participants not added by the application.
-	 */
-	public void naivePktReception(boolean doAccept) {
-		naiveReception = doAccept;
-	}
-	
-	/**
-	 * Are packets from unknown participants returned to the application?
-	 * 
-	 * @return whether we accept packets from participants not added by the application.
-	 */
-	public boolean naivePktReception() {
-		return naiveReception;
-	}
-	
-	/**
-	 * Set the number of RTP packets that should be buffered when a packet is
-	 * missing or received out of order. Setting this number high increases
-	 * the chance of correctly reordering packets, but increases latency when
-	 * a packet is dropped by the network.
-	 * 
-	 * Packets that arrive in order are not affected, they are passed straight
-	 * to the application.
-	 * 
-	 * The maximum delay is numberofPackets * packet rate , where the packet rate
-	 * depends on the codec and profile used by the sender.
-	 * 
-	 * Valid values:
-	 *  >0 - The maximum number of packets (based on RTP Timestamp) that may accumulate
-	 *  0 - All valid packets received in order will be given to the application
-	 * -1 - All valid packets will be given to the application
-	 * 
-	 * @param behavior the be
-	 * @return the behavior set, unchanged in the case of a erroneous value
-	 */
-	public int packetBufferBehavior(int behavior) {
-		if(behavior > -2) {
-			this.pktBufBehavior = behavior; 
-			// Signal the thread that pushes data to application
-			this.pktBufLock.lock();
-			try { this.pktBufDataReady.signalAll(); } finally {
-				this.pktBufLock.unlock();
-			}
-			return this.pktBufBehavior;
-		} else {
-			return this.pktBufBehavior;
-		}
-	}
-	
-	/**
-	 * The number of RTP packets that should be buffered when a packet is
-	 * missing or received out of order. A high number  increases the chance 
-	 * of correctly reordering packets, but increases latency when a packet is 
-	 * dropped by the network.
-	 * 
-	 * A negative value disables the buffering, out of order packets will simply be dropped.
-	 * 
-	 * @return the maximum number of packets that can accumulate before the first is returned
-	 */
-	public int packetBufferBehavior() {
-		return this.pktBufBehavior;
-	}
-	
-	/**
-	 * Set whether the stack should operate in RFC 4585 mode.
-	 * 
-	 * This will automatically call adjustPacketBufferBehavior(-1),
-	 * i.e. disable all RTP packet buffering in jlibrtp,
-	 * and disable frame reconstruction 
-	 * 
-	 * @param rtcpAVPFIntf the in
-	 */
-	public int registerAVPFIntf(RTCPAVPFIntf rtcpAVPFIntf, int maxDelay, int earlyThreshold, int regularThreshold ) {
-		if(this.rtcpSession != null) {
-			this.packetBufferBehavior(-1);
-			this.frameReconstruction = false;
-			this.rtcpAVPFIntf = rtcpAVPFIntf;
-			this.fbEarlyThreshold = earlyThreshold;
-			this.fbRegularThreshold = regularThreshold;	
-			return 0;
-		} else {
-			return -1;
-		}
-	}
-	
-	/**
-	 * Unregisters the RTCP AVPF interface, thereby going from
-	 * RFC 4585 mode to RFC 3550
-	 * 
-	 * You still have to adjust packetBufferBehavior() and
-	 * frameReconstruction.
-	 * 	
-	 */
-	public void unregisterAVPFIntf() {
-		this.fbEarlyThreshold = -1;
-		this.fbRegularThreshold = -1;	
-		this.rtcpAVPFIntf = null;
-	}
-	
-	/**
-	 * Enable / disable frame reconstruction in the packet buffers.
-	 * This is only relevant if getPacketBufferBehavior > 0;
-	 * 
-	 * Default is true.
-	 */
-	public void frameReconstruction(boolean toggle) {
-		this.frameReconstruction = toggle;
-	}
-	
-	/**
-	 * Whether the packet buffer will attempt to reconstruct
-	 * packet automatically.  
-	 * 
-	 * @return the status
-	 */
-	public boolean frameReconstruction() {
-		return this.frameReconstruction;
-	}
-	
-	/**
-	 * The bandwidth currently allocated to the session,
-	 * in bytes per second. The default is 8000.
-	 * 
-	 * This value is not enforced and currently only
-	 * used to calculate the RTCP interval to ensure the
-	 * control messages do not exceed 5% of the total bandwidth
-	 * described here.
-	 * 
-	 * Since the actual value may change a conservative
-	 * estimate should be used to avoid RTCP flooding.
-	 * 
-	 * see rtcpBandwidth(void)
-	 * 
-	 * @return current bandwidth setting
-	 */
-	public int sessionBandwidth() {
-		return this.bandwidth;
-	}
-	
-	/**
-	 * Set the bandwidth of the session.
-	 * 
-	 * See sessionBandwidth(void) for details. 
-	 * 
-	 * @param bandwidth the new value requested, in bytes per second
-	 * @return the actual value set
- 	 */
-	public int sessionBandwidth(int bandwidth) {
-		if(bandwidth < 1) {
-			this.bandwidth = 8000;
-		} else {
-			this.bandwidth = bandwidth;
-		}
-		return this.bandwidth;
-	}
-	
-	
-	/**
-	 * RFC 3550 dictates that 5% of the total bandwidth,
-	 * as set by sessionBandwidth, should be dedicated
-	 * to RTCP traffic. This 
-	 * 
-	 * This should normally not be done, but is permissible in 
-	 * conjunction with feedback (RFC 4585) and possibly
-	 * other profiles. 
-	 * 
-	 * Also see sessionBandwidth(void)
-	 * 
-	 * @return current RTCP bandwidth setting, -1 means not in use
-	 */
-	public int rtcpBandwidth() {
-		return this.rtcpBandwidth;
-	}
-	
-	/**
-	 * Set the RTCP bandwidth, see rtcpBandwidth(void) for details. 
-	 * 
-	 * This function must be
-	 * 
-	 * @param bandwidth the new value requested, in bytes per second or -1 to disable
-	 * @return the actual value set
- 	 */
-	public int rtcpBandwidth(int bandwidth) {
-		if(bandwidth < -1) {
-			this.rtcpBandwidth = -1;
-		} else {
-			this.rtcpBandwidth = bandwidth;
-		}
-		return this.rtcpBandwidth;
-	}
-	
-	/********************************************* Feedback message stuff ***************************************/
-	
-	/**
-	 * Adds a Picture Loss Indication to the feedback queue
-	 * 
-	 * @param ssrcMediaSource
-	 * @return 0 if packet was queued, -1 if no feedback support, 1 if redundant
-	 */
-	public int fbPictureLossIndication(long ssrcMediaSource) {
-		int ret = 0;
-		
-		if(this.rtcpAVPFIntf == null)
-			return -1;
-		
-		RtcpPktPSFB pkt = new RtcpPktPSFB(this.ssrc, ssrcMediaSource);
-		pkt.makePictureLossIndication();
-		ret = this.rtcpSession.addToFbQueue(ssrcMediaSource, pkt);
-		if(ret == 0)
-			this.rtcpSession.wakeSenderThread(ssrcMediaSource);
-		return ret; 
-	}
-	
-	/**
-	 * Adds a Slice Loss Indication to the feedback queue
-	 * 
-	 * @param ssrcMediaSource
-	 * @param sliFirst macroblock (MB) address of the first lost macroblock
-	 * @param sliNumber number of lost macroblocks
-	 * @param sliPictureId six least significant bits of the codec-specific identif
-	 * @return 0 if packet was queued, -1 if no feedback support, 1 if redundant
-	 */
-	public int fbSlicLossIndication(long ssrcMediaSource, int[] sliFirst, int[] sliNumber, int[] sliPictureId) {
-		int ret = 0;
-		if(this.rtcpAVPFIntf == null)
-			return -1;
-		
-		RtcpPktPSFB pkt = new RtcpPktPSFB(this.ssrc, ssrcMediaSource);
-		pkt.makeSliceLossIndication(sliFirst, sliNumber, sliPictureId);
-		
-		ret = this.rtcpSession.addToFbQueue(ssrcMediaSource, pkt);
-		if(ret == 0)
-			this.rtcpSession.wakeSenderThread(ssrcMediaSource);
-		return ret; 
-	}
-	
-	/**
-	 * Adds a Reference Picture Selection Indication to the feedback queue
-	 * 
-	 * @param ssrcMediaSource
-	 * @param bitPadding number of padded bits at end of bitString
-	 * @param payloadType RTP payload type for codec
-	 * @param bitString RPSI information as natively defined by the video codec
-	 * @return 0 if packet was queued, -1 if no feedback support, 1 if redundant
-	 */
-	public int fbRefPictureSelIndic(long ssrcMediaSource, int bitPadding, int payloadType, byte[] bitString) {
-		int ret = 0;
-		
-		if(this.rtcpAVPFIntf == null)
-			return -1;
-		
-		RtcpPktPSFB pkt = new RtcpPktPSFB(this.ssrc, ssrcMediaSource);
-		pkt.makeRefPictureSelIndic(bitPadding, payloadType, bitString);
-		ret = this.rtcpSession.addToFbQueue(ssrcMediaSource, pkt);
-		if(ret == 0)
-			this.rtcpSession.wakeSenderThread(ssrcMediaSource);
-		return ret; 
-	}
-	
-	/**
-	 * Adds a Picture Loss Indication to the feedback queue
-	 * 
-	 * @param ssrcMediaSource
-	 * @param bitString the original application message
-	 * @return 0 if packet was queued, -1 if no feedback support, 1 if redundant
-	 */
-	public int fbAppLayerFeedback(long ssrcMediaSource, byte[] bitString) {
-		int ret = 0;
-		
-		if(this.rtcpAVPFIntf == null)
-			return -1;
-		
-		RtcpPktPSFB pkt = new RtcpPktPSFB(this.ssrc, ssrcMediaSource);
-		pkt.makeAppLayerFeedback(bitString);
-		ret = this.rtcpSession.addToFbQueue(ssrcMediaSource, pkt);
-		if(ret == 0)
-			this.rtcpSession.wakeSenderThread(ssrcMediaSource);
-		return ret; 
-	}
-	
-	
-	/**
-	 * Adds a RTP Feedback packet to the feedback queue.
-	 * 
-	 * These are mostly used for NACKs.
-	 * 
-	 * @param ssrcMediaSource
-	 * @param FMT the Feedback Message Subtype
-	 * @param PID RTP sequence numbers of lost packets
-	 * @param BLP bitmask of following lost packets, shared index with PID 
-	 * @return 0 if packet was queued, -1 if no feedback support, 1 if redundant
-	 */
-	public int fbPictureLossIndication(long ssrcMediaSource, int FMT, int[] PID, int[] BLP) {
-		int ret = 0;
-		
-		if(this.rtcpAVPFIntf == null)
-			return -1;
-		
-		RtcpPktRTPFB pkt = new RtcpPktRTPFB(this.ssrc, ssrcMediaSource, FMT, PID, BLP);
-		ret = this.rtcpSession.addToFbQueue(ssrcMediaSource, pkt);
-		if(ret == 0)
-			this.rtcpSession.wakeSenderThread(ssrcMediaSource);
-		return ret; 
-	}
-		
-	/**
-	 * Fetches the next sequence number for RTP packets.
-	 * @return the next sequence number 
-	 */
-	private int getNextSeqNum() {
-		seqNum++;
-		// 16 bit number
-		if(seqNum > 65536) { 
-			seqNum = 0;
-		}
-		return seqNum;
-	}
-	
-	/** 
-	 * Initializes a random variable
-	 *
-	 */
-	private void createRandom() {
-		this.random = new Random(System.currentTimeMillis() + Thread.currentThread().getId() 
-				- Thread.currentThread().hashCode() + this.cname.hashCode());
-	}
-	
-	
-	/** 
-	 * Generates a random sequence number
-	 */
-	private void generateSeqNum() {
-		if(this.random == null)
-			createRandom();
-		
-		seqNum = this.random.nextInt();
-		if(seqNum < 0)
-			seqNum = -seqNum;
-		while(seqNum > 65535) {
-			seqNum = seqNum / 10;
-		}
-	}
-	
-	/**
-	 * Generates a random SSRC
-	 */
-	private void generateSsrc() {
-		if(this.random == null)
-			createRandom();
-		
-		// Set an SSRC
-		this.ssrc = this.random.nextInt();
-		if(this.ssrc < 0) {
-			this.ssrc = this.ssrc * -1;
-		}	
-	}
-	
-	/**
-	 * Resolve an SSRC conflict.
-	 * 
-	 * Also increments the SSRC conflict counter, after 5 conflicts
-	 * it is assumed there is a loop somewhere and the session will
-	 * terminate. 
-	 *
-	 */
-	protected void resolveSsrcConflict() {
-		System.out.println("!!!!!!! Beginning SSRC conflict resolution !!!!!!!!!");
-		this.conflictCount++;
-		
-		if(this.conflictCount < 5) {
-			//Don't send any more regular packets out until we have this sorted out.
-			this.conflict = true;
-		
-			//Send byes
-			rtcpSession.sendByes();
-		
-			//Calculate the next delay
-			rtcpSession.calculateDelay();
-			
-			//Generate a new Ssrc for ourselves
-			generateSsrc();
-			
-			//Get the SDES packets out faster
-			rtcpSession.initial = true;
-			
-			this.conflict = false;
-			System.out.println("SSRC conflict resolution complete");
-			
-		} else {
-			System.out.println("Too many conflicts. There is probably a loop in the network.");
-			this.endSession();
-		}
-	}
-}
--- a/src/jlibrtp/RtcpPkt.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.InetAddress;
-/** 
- * Common RTCP packet headers.
- *
- * @author Arne Kepp
- */
-public class RtcpPkt {
-	/** Whether a problem has been encountered during parsing */
-	protected int problem = 0;
-	/** The version, always 2, 2 bits */
-	protected int version = 2;
-	/** Padding , 1 bit */
-	protected int padding = 0;
-	/** Number of items, e.g. receiver report blocks. Usage may vary. 5 bits */
-	protected int itemCount = 0;
-	/** The type of RTCP packet, 8 bits */
-	protected int packetType = -1;
-	/** The length of the RTCP packet, in 32 bit blocks minus 1. 16 bits*/
-	protected int length = -1;
-	/** The ssrc that sent this, usually dictated by RTP Session */
-	protected long ssrc = -1;
-	
-	/** Contains the actual data (eventually) */
-	protected byte[] rawPkt = null;
-	
-	/** Only used for feedback messages: Time message was generated */
-	protected long time = -1;
-	/** Only used for feedback message: Whether this packet was received */
-	protected boolean received = false;
-	
-	
-	/**
-	 * Parses the common header of an RTCP packet
-	 * 
-	 * @param start where in this.rawPkt the headers start
-	 * @return true if parsing succeeded and header cheks 
-	 */
-	protected boolean parseHeaders(int start) {
-		version = ((rawPkt[start+0] & 0xC0) >>> 6);
-		padding = ((rawPkt[start+0] & 0x20) >>> 5);
-		itemCount = (rawPkt[start+0] & 0x1F);
-		packetType = (int) rawPkt[start+1];
-		if(packetType < 0) {
-			packetType += 256;
-		}
-		length = StaticProcs.bytesToUIntInt(rawPkt, start+2);
-		
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println(" <-> RtcpPkt.parseHeaders() version:"+version+" padding:"+padding+" itemCount:"+itemCount
-					+" packetType:"+packetType+" length:"+length);
-		}
-		
-		if(packetType > 207 || packetType < 200) 
-			System.out.println("RtcpPkt.parseHeaders problem discovered, packetType " + packetType);
-		
-		if(version == 2 && length < 65536) {
-			return true;
-		} else {
-			System.out.println("RtcpPkt.parseHeaders() failed header checks, check size and version");
-			this.problem = -1;
-			return false;
-		}
-	}
-	/**
-	 * Writes the common header of RTCP packets. 
-	 * The values should be filled in when the packet is initiliazed and this function
-	 * called at the very end of .encode()
-	 */
-	protected void writeHeaders() {
-		byte aByte = 0;
-		aByte |=(version << 6);
-		aByte |=(padding << 5);
-		aByte |=(itemCount);
-		rawPkt[0] = aByte;
-		aByte = 0;
-		aByte |= packetType;
-		rawPkt[1] = aByte;
-		if(rawPkt.length % 4 != 0)
-			System.out.println("!!!! RtcpPkt.writeHeaders() rawPkt was not a multiple of 32 bits / 4 octets!");
-		byte[] someBytes = StaticProcs.uIntIntToByteWord((rawPkt.length / 4) - 1);
-		rawPkt[2] = someBytes[0];
-		rawPkt[3] = someBytes[1];
-	}
-	
-	/**
-	 * This is just a dummy to make Eclipse complain less.
-	 */
-	protected void encode() {
-		System.out.println("RtcpPkt.encode() should never be invoked!! " + this.packetType);
-	}
-	
-	/**
-	 * Check whether this packet came from the source we expected.
-	 * 
-	 * Not currently used!
-	 * 
-	 * @param adr address that packet came from
-	 * @param partDb the participant database for the session
-	 * @return true if this packet came from the expected source
-	 */
-	protected boolean check(InetAddress adr, ParticipantDatabase partDb) {
-		//Multicast -> We have to be naive
-		if (partDb.rtpSession.mcSession && adr.equals(partDb.rtpSession.mcGroup))
-			return true;
-		
-		//See whether this participant is known
-		Participant part = partDb.getParticipant(this.ssrc);
-		if(part != null && part.rtcpAddress.getAddress().equals(adr))
-			return true;
-		
-		//If not, we should look for someone without SSRC with his ip-address?
-		return false;
-	}
-}
--- a/src/jlibrtp/RtcpPktAPP.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * Application specific RTCP packets
- * 
- * @author Arne Kepp
- */
-public class RtcpPktAPP extends RtcpPkt {
-	/** Name of packet, 4 bytes ASCII */
-	protected byte[] pktName = null;
-	/** Data of packet */
-	protected byte[] pktData = null;	
-	
-	/**
-	 * Constructor for a new Application RTCP packet
-	 * 
-	 * @param ssrc the SSRC of the sender, presumably taken from RTPSession
-	 * @param subtype the subtype of packet, application specific
-	 * @param pktName byte[4] representing ASCII name of packet
-	 * @param pktData the byte[4x] data that represents the message itself
-	 */
-	protected RtcpPktAPP(long ssrc, int subtype, byte[] pktName, byte[] pktData) {
-		// Fetch all the right stuff from the database
-		super.ssrc = ssrc;
-		super.packetType = 204;
-		super.itemCount = subtype;
-		this.pktName = pktName;
-		this.pktData = pktData;
-	}
-	
-	/**
-	 * Constructor that parses a received Application RTCP packet
-	 * 
-	 * @param aRawPkt the raw packet containing the date
-	 * @param start where in the raw packet this packet starts
-	 */
-	protected RtcpPktAPP(byte[] aRawPkt, int start) {
-		super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4);
-		super.rawPkt = aRawPkt;
-		
-		if(!super.parseHeaders(start) || packetType != 204 ) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktAPP.parseHeaders() etc. problem");
-			}
-			super.problem = -204;
-		} else {
-			//System.out.println("super.length:  " + super.length);
-			if(super.length > 1) {
-				pktName = new byte[4];
-				System.arraycopy(aRawPkt, 8, pktName, 0, 4);
-			}
-			if(super.length > 2) {
-				pktData = new byte[(super.length+1)*4 - 12];
-				System.arraycopy(aRawPkt, 12, pktData, 0, pktData.length);
-			}
-		}
-	}
-	
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {	
-		super.rawPkt = new byte[12 + this.pktData.length];
-		byte[] tmp = StaticProcs.uIntLongToByteWord(super.ssrc);
-		System.arraycopy(tmp, 0, super.rawPkt, 4, 4);
-		System.arraycopy(this.pktName, 0, super.rawPkt, 8, 4);
-		System.arraycopy(this.pktData, 0, super.rawPkt, 12, this.pktData.length);
-		writeHeaders();
-		//System.out.println("ENCODE: " + super.length + " " + rawPkt.length + " " + pktData.length);
-	}
-}
--- a/src/jlibrtp/RtcpPktBYE.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RTCP packets for sending Bye messages
- * 
- * @author Arne Kepp
- */
-public class RtcpPktBYE extends RtcpPkt {
-	/** SSRCs saying bye, 32xn bits, n<16 */
-	protected long[] ssrcArray = null;
-	/** Optional reason */
-	protected byte[] reason = null;
-	
-	protected RtcpPktBYE(long[] ssrcs,byte[] aReason) {
-		super.packetType = 203;
-		// Fetch all the right stuff from the database
-		reason = aReason;
-		ssrcArray = ssrcs;
-		if(ssrcs.length < 1) {
-			System.out.println("RtcpBYE.RtcpPktBYE(long[] ssrcs, byte[] aReason) requires at least one SSRC!");
-		}
-	}
-	
-	protected RtcpPktBYE(byte[] aRawPkt, int start) {
-		rawPkt = aRawPkt;
-		if(!super.parseHeaders(start) || packetType != 203 ) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktBYE.parseHeaders() etc. problem");
-			}
-			super.problem = -203;
-		} else {
-			ssrcArray = new long[super.itemCount];
-			
-			for(int i=0; i<super.itemCount; i++) {
-				ssrcArray[i] = StaticProcs.bytesToUIntLong(aRawPkt, start + (i+1)*4);
-			}
-			if(super.length > (super.itemCount + 1)) {
-				int reasonLength = (int) aRawPkt[start + (super.itemCount+1)*4];
-				//System.out.println("super.itemCount:"+super.itemCount+" reasonLength:"+reasonLength+" start:"+(super.itemCount*4 + 4 + 1));
-				reason = new byte[reasonLength];
-				System.arraycopy(aRawPkt, start + (super.itemCount + 1)*4 + 1, reason, 0, reasonLength);
-				//System.out.println("test:" + new String(reason));
-			}
-		}
-	}
-	
-	protected void encode() {			
-		itemCount = ssrcArray.length;
-		length = 4*ssrcArray.length;
-		
-		if(reason != null) {
-			length += (reason.length + 1)/4;
-			if((reason.length + 1) % 4 != 0) {
-				length +=1;
-			}
-		}
-		rawPkt = new byte[length*4 + 4];
-		
-		int i;
-		byte[] someBytes;
-		
-		// SSRCs
-		for(i=0; i<ssrcArray.length; i++ ) {
-			someBytes = StaticProcs.uIntLongToByteWord(ssrcArray[i]);
-			System.arraycopy(someBytes, 0, rawPkt, 4 + 4*i, 4);			
-		}
-		
-		// Reason for leaving
-		if(reason != null) {
-			//System.out.println("Writing to:"+(4+4*ssrcArray.length)+ " reason.length:"+reason.length );
-			rawPkt[(4 + 4*ssrcArray.length)] = (byte) reason.length;
-			System.arraycopy(reason, 0, rawPkt, 4+4*i +1, reason.length);		
-		}
-		super.writeHeaders();
-	}
-	
-	public void debugPrint() {
-		System.out.println("RtcpPktBYE.debugPrint() ");
-		if(ssrcArray != null) {
-			for(int i= 0; i<ssrcArray.length; i++) {
-				long anSsrc = ssrcArray[i];
-				System.out.println("     ssrc: " + anSsrc);
-			}
-		}
-		if(reason != null) {
-			System.out.println("     Reason: " + new String(reason));
-		}
-	}
-}
\ No newline at end of file
--- a/src/jlibrtp/RtcpPktPSFB.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RTCP packets for Payload-Specific Feedback Messages 
- * 
- * @author Arne Kepp
- */
-public class RtcpPktPSFB extends RtcpPkt {
-	/** If this packet was for a different SSRC */
-	protected boolean notRelevant = false;
-	/** Parent RTP Session */
-	private RTPSession rtpSession;
-	/** SSRC we are sending feeback to */
-	protected long ssrcMediaSource = -1;
-	 
-	/** SLI macroblock (MB) address of the first lost macroblock number */
-	protected int[] sliFirst;
-	/** SLI number of lost macroblocks */
-	protected int[] sliNumber;
-	/** SLI six least significant bits of the codec-specific identifier */
-	protected int[] sliPictureId;
-	
-	// Picture loss indication
-	/** RPSI number of padded bits at end of bitString */
-	protected int rpsiPadding = -1;
-	/** RPSI payloadType RTP payload type */
-	protected int rpsiPayloadType = -1;
-	/** RPSI information as natively defined by the video codec */
-	protected byte[] rpsiBitString;
-	
-	/** Application Layer Feedback Message */
-	protected byte[] alfBitString;
-	
-	/**
-	 * Generic constructor, then call make<something>
-	 * 
-	 * @param ssrcPacketSender
-	 * @param ssrcMediaSource
-	 */
-	protected RtcpPktPSFB(long ssrcPacketSender, long ssrcMediaSource) {
-		super.ssrc = ssrcPacketSender;
-		this.ssrcMediaSource = ssrcMediaSource;
-		super.packetType = 206; //PSFB
-	}
-	
-	/**
-	 * Make this packet a Picture loss indication
-	 */
-	protected void makePictureLossIndication() {
-		super.itemCount = 1; //FMT
-	}
-	
-	/**
-	 * Make this packet a Slice Loss Indication
-	 * 
-	 * @param sliFirst macroblock (MB) address of the first lost macroblock
-	 * @param sliNumber number of lost macroblocks
-	 * @param sliPictureId six least significant bits of the codec-specific identifier
-	 */
-	protected void makeSliceLossIndication(int[] sliFirst, int[] sliNumber, int[] sliPictureId) {
-		super.itemCount = 2; //FMT
-		this.sliFirst = sliFirst;
-		this.sliNumber = sliNumber;
-		this.sliPictureId = sliPictureId;
-	}
-	
-	/**
-	 * Make this packet a Reference Picture Selection Indication
-	 * 
-	 * @param bitPadding number of padded bits at end of bitString
-	 * @param payloadType RTP payload type for codec
-	 * @param bitString RPSI information as natively defined by the video codec
-	 */
-	protected void makeRefPictureSelIndic(int bitPadding, int payloadType, byte[] bitString) {
-		super.itemCount = 3; //FMT
-		this.rpsiPadding = bitPadding;
-		this.rpsiPayloadType = payloadType;
-		this.rpsiBitString = bitString;
-	}
-	
-	/** 
-	 * Make this packet an Application specific feedback message
-	 * 
-	 * @param bitString the original application message
-	 */
-	protected void makeAppLayerFeedback(byte[] bitString) {
-		super.itemCount = 15; //FMT
-		this.alfBitString = bitString; 
-	}
-	
-	/**
-	 * Constructor that parses a raw packet to retrieve information
-	 * 
-	 * @param aRawPkt the raw packet to be parsed
-	 * @param start the start of the packet, in bytes
-	 * @param rtpSession the session on which the callback interface resides
-	 */
-	protected RtcpPktPSFB(byte[] aRawPkt, int start, RTPSession rtpSession) {		
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("  -> RtcpPktPSFB(byte[], int start)");
-		}
-		this.rtpSession = rtpSession;
-		
-		rawPkt = aRawPkt;
-
-		if(! super.parseHeaders(start) || packetType != 206 || super.length < 2 ) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktRTPFB.parseHeaders() etc. problem");
-			}
-			super.problem = -206;
-		} else {
-			//FMT = super.itemCount;
-			ssrcMediaSource = StaticProcs.bytesToUIntLong(aRawPkt,8+start);
-			
-			if(ssrcMediaSource == rtpSession.ssrc) {
-				super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4+start);
-				
-				switch(super.itemCount) {
-				case 1: // Picture Loss Indication 
-					decPictureLossIndic();
-					break; 
-				case 2: // Slice Loss Indication
-					decSliceLossIndic(aRawPkt, start + 12); 
-					break;
-				case 3: // Reference Picture Selection Indication 
-					decRefPictureSelIndic(aRawPkt, start + 12); 
-					break;
-				case 15: // Application Layer Feedback Messages
-					decAppLayerFB(aRawPkt, start + 12); 
-					break;
-				default: 
-					System.out.println("!!!! RtcpPktPSFB(byte[], int start) unexpected FMT " + super.itemCount);
-				}
-			} else {
-				this.notRelevant = true;
-			}
-		}
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("  <- RtcpPktPSFB()");
-		}
-	}
-	
-	/**
-	 * Decode Picture Loss indication
-	 *
-	 */
-	private void decPictureLossIndic() {
-		if(this.rtpSession.rtcpAVPFIntf != null) {
-			this.rtpSession.rtcpAVPFIntf.PSFBPktPictureLossReceived(
-					super.ssrc);
-		}
-	}
-	
-	/**
-	 * Decode Slice Loss Indication
-	 * 
-	 * @param aRawPkt
-	 * @param start
-	 */
-	private void decSliceLossIndic(byte[] aRawPkt, int start) {	
-		// 13 bit off-boundary numbers? That's rather cruel
-		//    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-		//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-		//   |            First        |        Number           | PictureID |
-		//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-				
-		int count = super.length - 2;
-		
-		sliFirst = new int[count];
-		sliNumber = new int[count];
-		sliPictureId = new int[count];
-		
-		// Loop over the FCI lines
-		for(int i=0; i < count; i++) {
-			sliFirst[i] = StaticProcs.bytesToUIntInt(aRawPkt, start) >> 3;
-			sliNumber[i] = (int) (StaticProcs.bytesToUIntInt(aRawPkt, start) & 0x0007FFC0) >> 6;
-			sliPictureId[i] = (StaticProcs.bytesToUIntInt(aRawPkt, start + 2) & 0x003F);
-			start += 4;
-		}
-		
-		if(this.rtpSession.rtcpAVPFIntf != null) {
-			this.rtpSession.rtcpAVPFIntf.PSFBPktSliceLossIndic(
-					super.ssrc,
-					sliFirst, sliNumber, sliPictureId);
-		}
-	}
-	
-	/**
-	 * Decode Reference Picture Selection Indication
-	 * 
-	 * @param aRawPkt
-	 * @param start
-	 */
-	private void decRefPictureSelIndic(byte[] aRawPkt, int start) {	
-		//  0                   1                   2                   3
-		//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-		// |      PB       |0| Payload Type|    Native RPSI bit string     |
-		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-		// |   defined per codec          ...                | Padding (0) |
-		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-		
-		rpsiPadding = aRawPkt[start];
-		
-		if(rpsiPadding  > 32) {
-			System.out.println("!!!! RtcpPktPSFB.decRefPictureSelcIndic paddingBits: " 
-					+ rpsiPadding);
-		}
-		
-		rpsiPayloadType = (int) rawPkt[start];
-		if(rpsiPayloadType < 0) {
-			System.out.println("!!!! RtcpPktPSFB.decRefPictureSelcIndic 8th bit not zero: " 
-					+ rpsiPayloadType);
-		}
-		
-		rpsiBitString = new byte[(super.length - 2)*4 - 2];
-		System.arraycopy(aRawPkt, start + 2, rpsiBitString, 0, rpsiBitString.length);
-		
-		if(this.rtpSession.rtcpAVPFIntf != null) {
-			this.rtpSession.rtcpAVPFIntf.PSFBPktRefPictureSelIndic(
-					super.ssrc,
-					rpsiPayloadType, rpsiBitString, rpsiPadding);
-		}
-		
-	}
-	
-	/**
-	 * Decode Application specific feedback message
-	 * 
-	 * @param aRawPkt
-	 * @param start
-	 */
-	private void decAppLayerFB(byte[] aRawPkt, int start) {	
-		//Application Message (FCI): variable length
-		int stringLength = (super.length - 2)*4;
-		
-		alfBitString = new byte[stringLength];
-		
-		System.arraycopy(aRawPkt, start, alfBitString, 0, stringLength);
-
-		if(this.rtpSession.rtcpAVPFIntf != null) {
-			this.rtpSession.rtcpAVPFIntf.PSFBPktAppLayerFBReceived(
-					super.ssrc, alfBitString);
-		}
-	}
-	
-
-	
-	/**
-	 * Encode a Slice Loss Indication
-	 */
-	private void encSliceLossIndic() {
-		byte[] firstBytes;
-		byte[] numbBytes;
-		byte[] picBytes;
-		
-		int offset = 8;
-		// Loop over the FCI lines
-		for(int i=0; i < sliFirst.length; i++) {
-			offset = 8 + 8*i;
-			firstBytes = StaticProcs.uIntLongToByteWord(sliFirst[i] << 3);
-			numbBytes = StaticProcs.uIntLongToByteWord(sliNumber[i] << 2);
-			picBytes = StaticProcs.uIntIntToByteWord(sliPictureId[i]);
-			
-			super.rawPkt[offset] = firstBytes[2];
-			super.rawPkt[offset+1] = (byte) (firstBytes[3] | numbBytes[2]);
-			super.rawPkt[offset+2] = numbBytes[3];
-			super.rawPkt[offset+3] = (byte) (numbBytes[3] | picBytes[1]);
-		}
-	}
-	
-	/**
-	 * Encode a Reference Picture Selection Indication
-	 *
-	 */
-	private void encRefPictureSelIndic() {	
-		byte[] someBytes;
-		someBytes = StaticProcs.uIntIntToByteWord(rpsiPadding);
-		super.rawPkt[8] = someBytes[1];
-		someBytes = StaticProcs.uIntIntToByteWord(rpsiPayloadType);
-		super.rawPkt[9] = someBytes[1];
-		
-		System.arraycopy(rpsiBitString, 0, super.rawPkt, 10, rpsiBitString.length);
-	}
-	
-	
-	/**
-	 * Encode Application Layer Feedback
-	 *
-	 */
-	private void encAppLayerFB() {	
-		//Application Message (FCI): variable length
-		System.arraycopy(alfBitString, 0, super.rawPkt, 8, alfBitString.length);
-	}
-	
-	/** 
-	 * Get the FMT (Feedback Message Type)
-	 * @return value stored in .itemcount, same field
-	 */
-	protected int getFMT() {
-		return this.itemCount;
-	}
-	
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {
-		switch(super.itemCount) {
-		case 1: // Picture Loss Indication 
-			//Nothing to do really
-			super.rawPkt = new byte[24];
-			break; 
-		case 2: // Slice Loss Indication
-			super.rawPkt = new byte[24 + 4*this.sliFirst.length];
-			encSliceLossIndic(); 
-			break;
-		case 3: // Reference Picture Selection Indication
-			super.rawPkt = new byte[24 + 2 + this.rpsiBitString.length/4];
-			encRefPictureSelIndic();
-			break;
-		case 15: // Application Layer Feedback Messages
-			super.rawPkt = new byte[24 + this.alfBitString.length/4];
-			encAppLayerFB();
-			break;
-		}
-		
-		byte[] someBytes = StaticProcs.uIntLongToByteWord(super.ssrc);
-		System.arraycopy(someBytes, 0, super.rawPkt, 4, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(this.ssrcMediaSource);
-		System.arraycopy(someBytes, 0, super.rawPkt, 8, 4);
-		
-		writeHeaders();
-	}
-
-	/**
-	 * Debug purposes only
-	 */
-	public void debugPrint() {
-		System.out.println("->RtcpPktPSFB.debugPrint() ");
-		
-		String str;
-		switch(super.itemCount) {
-		case 1: // Picture Loss Indication 
-			System.out.println("  FMT: Picture Loss Indication");
-			break; 
-		case 2: // Slice Loss Indication
-			if(sliFirst != null) {
-				str = "sliFirst[].length: " + sliFirst.length;
-			} else {
-				str = "sliFirst[] is null";
-			}
-			System.out.println("  FMT: Slice Loss Indication, " + str);
-			break;
-		case 3: // Reference Picture Selection Indication
-			if(rpsiBitString != null) {
-				str = "rpsiBitString[].length: " + rpsiBitString.length;
-			} else {
-				str = "rpsiBitString[] is null";
-			}
-			System.out.println("  FMT: Reference Picture Selection Indication, " 
-					+ str + " payloadType: " + this.rpsiPayloadType);
-			break;
-		case 15: // Application Layer Feedback Messages
-			if(alfBitString != null) {
-				str = "alfBitString[].length: " + alfBitString.length;
-			} else {
-				str = "alfBitString[] is null";
-			}
-			System.out.println("  FMT: Application Layer Feedback Messages, " + str);
-			break;
-		}
-
-		System.out.println("<-RtcpPktPSFB.debugPrint() ");
-	}
-}
--- a/src/jlibrtp/RtcpPktRR.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RTCP packets for Receiver Reports 
- * 
- * @author Arne Kepp
- */
-public class RtcpPktRR extends RtcpPkt {
-	/** Array of participants to send Receiver Reports to */
-	protected Participant[] reportees = null;
-	/** SSRC of participants the reports are for */
-	protected long[] reporteeSsrc = null;// -1; //32 bits
-	/** Fraction (over 256) of packets lost */
-	protected int[] lossFraction = null;//-1; //8 bits
-	/** Number of lost packets */
-	protected int[] lostPktCount = null;//-1; //24 bits
-	/** Extended highest sequence received */
-	protected long[] extHighSeqRecv = null;//-1; //32 bits
-	/** Interarrival jitter*/
-	protected long[] interArvJitter = null;//-1; //32 bits
-	/** Middle 32 bits of NTP when last SR was received */
-	protected long[] timeStampLSR = null;//-1; //32 bits
-	/** Delay on last SRC */
-	protected long[] delaySR = null;//-1; //32 bits
-	
-	/**
-	 * Constructor for a packet with receiver reports
-	 * 
-	 * @param reportees the participants on which to generate reports
-	 * @param ssrc the SSRC of the sender, from the RTPSession
-	 */
-	protected RtcpPktRR(Participant[] reportees, long ssrc) {
-		super.packetType = 201;
-		// Fetch all the right stuff from the database
-		super.ssrc = ssrc;
-		this.reportees = reportees;
-	}
-
-
-	/**
-	 * 
-	 * 
-	 * If rcount < 0 we assume we have to parse the entire packet,
-	 * otherwise we'll just parse the receiver report blocks
-	 * (ie. the data came from a Sender Report packet)
-	 * 
-	 * @param aRawPkt the byte[] with the report(s)
-	 * @param start where in the raw packet to start reading
-	 * @param rrCount the number of receiver reports, -1 if this does not come from an SR
-	 */
-	protected RtcpPktRR(byte[] aRawPkt, int start, int rrCount) {
-		//System.out.println("RtcpPktRR: " + rrCount + "  start: " + start);
-		super.rawPkt = aRawPkt;
-		
-		if(rrCount < 0 && (!super.parseHeaders(start) || packetType != 201 || super.length < 1)) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktRR.parseHeaders() etc. problem: "+(!super.parseHeaders(start))+" "+packetType+" "+super.length);
-			}
-			super.problem = -201;
-		}
-		
-		int base;
-		if(rrCount > 0) {
-			base = start + 28;
-		} else {
-			base = start + 8;
-			rrCount = super.itemCount;
-			super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt, start + 4);
-		}
-		
-		if(rrCount > 0) {
-			reporteeSsrc = new long[rrCount];
-			lossFraction = new int[rrCount];
-			lostPktCount = new int[rrCount];
-			extHighSeqRecv = new long[rrCount];
-			interArvJitter = new long[rrCount];
-			timeStampLSR = new long[rrCount];
-			delaySR = new long[rrCount];
-
-			for(int i=0; i<rrCount; i++ ) {
-				int pos = base + i*24;
-				reporteeSsrc[i] = StaticProcs.bytesToUIntLong(aRawPkt, pos);
-				lossFraction[i] = (int) aRawPkt[pos + 4];
-				aRawPkt[pos + 4] = (byte) 0;
-				lostPktCount[i] = (int) StaticProcs.bytesToUIntLong(aRawPkt, pos + 4);
-				extHighSeqRecv[i] = StaticProcs.bytesToUIntLong(aRawPkt, pos + 8);
-				interArvJitter[i] = StaticProcs.bytesToUIntLong(aRawPkt, pos + 12);
-				timeStampLSR[i] = StaticProcs.bytesToUIntLong(aRawPkt, pos + 16);
-				delaySR[i] = StaticProcs.bytesToUIntLong(aRawPkt, pos + 20);
-			}
-		}
-	}
-	
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println("  -> RtcpPktRR.encode()");
-		}
-		
-		byte[] rRs = null;
-		//Gather up the actual receiver reports
-		if(this.reportees != null) {
-			rRs = this.encodeRR();
-			super.rawPkt = new byte[rRs.length + 8];
-			System.arraycopy(rRs, 0, super.rawPkt, 8, rRs.length);
-			super.itemCount = reportees.length;
-		} else {
-			super.rawPkt = new byte[8];
-			super.itemCount = 0;	
-		}
-		
-		//Write the common header
-		super.writeHeaders();
-		
-		//Add our SSRC (as sender)
-		byte[] someBytes;
-		someBytes = StaticProcs.uIntLongToByteWord(super.ssrc);
-		System.arraycopy(someBytes, 0, super.rawPkt, 4, 4);
-		
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println("  <- RtcpPktRR.encode()");
-		}
-		
-	}
-	
-	/**
-	 * Encodes the individual Receiver Report blocks, 
-	 * 
-	 * so they can be used either in RR packets or appended to SR
-	 * 
-	 * @return the encoded packets
-	 */
-	protected byte[] encodeRR() {
-		if(RTPSession.rtpDebugLevel > 10) {
-			System.out.println("   -> RtcpPktRR.encodeRR()");
-		}
-		//assuming we will always create complete reports:
-		byte[] ret = new byte[24*reportees.length];
-		
-		//Write SR stuff
-		for(int i = 0; i<reportees.length; i++) {
-			int offset = 24*i;
-			byte[] someBytes = StaticProcs.uIntLongToByteWord(reportees[i].ssrc);
-			System.arraycopy(someBytes, 0, ret, offset, 4);
-			
-			//Cumulative number of packets lost
-			someBytes = StaticProcs.uIntLongToByteWord(reportees[i].getLostPktCount());
-		
-			someBytes[0] = (byte) reportees[i].getFractionLost();
-		
-			//Write Cumulative number of packets lost and loss fraction to packet:
-			System.arraycopy(someBytes, 0, ret, 4 + offset, 4);
-		
-			// Extended highest sequence received
-			someBytes = StaticProcs.uIntLongToByteWord(reportees[i].getExtHighSeqRecv());
-			System.arraycopy(someBytes, 0, ret, 8 + offset, 4);
-		
-			// Interarrival jitter
-			if(reportees[i].interArrivalJitter >= 0) {
-				someBytes = StaticProcs.uIntLongToByteWord((long)reportees[i].interArrivalJitter);
-			} else { 
-				someBytes = StaticProcs.uIntLongToByteWord((long) 0); 
-			}
-			System.arraycopy(someBytes, 0, ret, 12 + offset, 4);
-		
-			// Timestamp last sender report received
-			someBytes = StaticProcs.uIntLongToByteWord(reportees[i].timeStampLSR);
-			System.arraycopy(someBytes, 0, ret, 16 + offset, 4);
-		
-			// Delay since last sender report received, in terms of 1/655536 s = 0.02 ms
-			if(reportees[i].timeReceivedLSR > 0) {
-				someBytes = StaticProcs.uIntLongToByteWord(reportees[i].delaySinceLastSR());
-			} else {
-				someBytes = StaticProcs.uIntLongToByteWord(0);
-			}
-			System.arraycopy(someBytes, 0, ret, 20 + offset, 4);
-		}
-		if(RTPSession.rtpDebugLevel > 10) {
-			System.out.println("   <- RtcpPktRR.encodeRR()");
-		}
-		return ret;
-	}
-	
-	/**
-	 * Debug purposes only
-	 */
-	public void debugPrint() {
-		System.out.println("RtcpPktRR.debugPrint() ");
-		if(reportees != null) {
-			for(int i= 0; i<reportees.length; i++) {
-				Participant part = reportees[i];
-				System.out.println("     part.ssrc: " + part.ssrc + "  part.cname: " + part.cname);
-			}
-		} else {
-			for(int i=0;i<reporteeSsrc.length; i++) {
-				System.out.println("     reporteeSSRC: " + reporteeSsrc[i] + "  timeStampLSR: " + timeStampLSR[i]);
-			}
-		}
-	}
-}
--- a/src/jlibrtp/RtcpPktRTPFB.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RTCP packets for RTP Feedback Messages 
- * 
- * In line with RFC 4585, this packet currently only supports NACKs
- * 
- * @author Arne Kepp
- */
-public class RtcpPktRTPFB extends RtcpPkt {
-	/** If this packet was for a different SSRC */
-	protected boolean notRelevant = false;
-	/** SSRC we are sending feeback to */
-	protected long ssrcMediaSource = -1;
-	/** RTP sequence numbers of lost packets */
-	protected int PID[];
-	/** bitmask of following lost packets, shared index with PID */
-	protected int BLP[];
-	
-	/**
-	 * Constructor for RTP Feedback Message
-	 * 
-	 * @param ssrcPacketSender SSRC of sender, taken from RTPSession
-	 * @param ssrcMediaSource SSRC of recipient of this message
-	 * @param FMT the Feedback Message Subtype
-	 * @param PID RTP sequence numbers of lost packets
-	 * @param BLP bitmask of following lost packets, shared index with PID 
-	 */
-	protected RtcpPktRTPFB(long ssrcPacketSender, long ssrcMediaSource, int FMT, int[] PID, int[] BLP) {
-		super.packetType = 205; //RTPFB
-		super.itemCount = FMT; 
-		this.PID = PID;
-		this.BLP = BLP;
-	}
-	
-	/**
-	 * Constructor that parses a raw packet to retrieve information
-	 * 
-	 * @param aRawPkt the raw packet to be parsed
-	 * @param start the start of the packet, in bytes
-	 * @param rtpSession the session on which the callback interface resides
-	 */
-	protected RtcpPktRTPFB(byte[] aRawPkt, int start, RTPSession rtpSession) {		
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("  -> RtcpPktRTPFB(byte[], int start)");
-		}
-		
-		rawPkt = aRawPkt;
-
-		if(! super.parseHeaders(start) || packetType != 205 || super.length < 2) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktRTPFB.parseHeaders() etc. problem");
-			}
-			super.problem = -205;
-		} else {
-			//FMT = super.itemCount;
-			
-			ssrcMediaSource = StaticProcs.bytesToUIntLong(aRawPkt,8+start);
-			
-			if(ssrcMediaSource == rtpSession.ssrc) {
-				super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4+start);
-				int loopStop = super.length - 2;
-				PID = new int[loopStop];
-				BLP = new int[loopStop];
-				int curStart = 12;
-
-				// Loop over Feedback Control Information (FCI) fields
-				for(int i=0; i< loopStop; i++) {
-					PID[i] = StaticProcs.bytesToUIntInt(aRawPkt, curStart);
-					BLP[i] = StaticProcs.bytesToUIntInt(aRawPkt, curStart + 2);
-					curStart += 4;
-				}
-
-				rtpSession.rtcpAVPFIntf.RTPFBPktReceived(
-						super.ssrc, super.itemCount, PID, BLP);
-			}
-		}
-		
-
-		
-		if(RTPSession.rtpDebugLevel > 8) {
-			System.out.println("  <- RtcpPktRTPFB()");
-		}
-	}
-	
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {
-		super.rawPkt = new byte[12 + this.PID.length*4];
-		
-		byte[] someBytes = StaticProcs.uIntLongToByteWord(super.ssrc);
-		System.arraycopy(someBytes, 0, super.rawPkt, 4, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(this.ssrcMediaSource);
-		System.arraycopy(someBytes, 0, super.rawPkt, 8, 4);
-		
-		// Loop over Feedback Control Information (FCI) fields
-		int curStart = 12;
-		for(int i=0; i < this.PID.length; i++ ) {
-			someBytes = StaticProcs.uIntIntToByteWord(PID[i]);
-			super.rawPkt[curStart++] = someBytes[0];
-			super.rawPkt[curStart++] = someBytes[1];
-			someBytes = StaticProcs.uIntIntToByteWord(BLP[i]);
-			super.rawPkt[curStart++] = someBytes[0];
-			super.rawPkt[curStart++] = someBytes[1];
-		}
-		writeHeaders();
-	}
-	
-	/** 
-	 * Get the FMT (Feedback Message Type)
-	 * @return value stored in .itemcount, same field
-	 */
-	protected int getFMT() {
-		return this.itemCount;
-	}
-	
-	/**
-	 * Debug purposes only
-	 */
-	protected void debugPrint() {
-		System.out.println("->RtcpPktRTPFB.debugPrint() ");
-		System.out.println("  ssrcPacketSender: " + super.ssrc + "  ssrcMediaSource: " + ssrcMediaSource);
-		
-		if(this.PID != null && this.PID.length < 1) {
-			System.out.println("  No Feedback Control Information (FCI) fields");
-		}
-		
-		for(int i=0; i < this.PID.length; i++ ) {
-			System.out.println("  FCI -> PID: " + PID[i] + "  BLP: " + BLP[i]);
-		}
-		System.out.println("<-RtcpPktRTPFB.debugPrint() ");
-	}
-}
--- a/src/jlibrtp/RtcpPktSDES.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.InetSocketAddress;
-
-/**
- * RTCP packets for Source Descriptions
- * 
- * @author Arne Kepp
- */
-public class RtcpPktSDES extends RtcpPkt {
-	/** Whether the RTP Session object should be inclduded */
-	boolean reportSelf = true;
-	/** The parent RTP Session object, holds participant database */
-	RTPSession rtpSession = null;
-	/** The participants to create SDES packets for */
-	protected Participant[] participants = null;
-	
-	/**
-	 * Constructor to create a new SDES packet
-	 * 
-	 * TODO:
-	 * Currently the added participants are not actually encoded
-	 * because the library lacks some support for acting as mixer or
-	 * relay in other areas.
-	 * 
-	 * @param reportThisSession include information from RTPSession as a participant
-	 * @param rtpSession the session itself
-	 * @param additionalParticipants additional participants to include
-	 */
-	protected RtcpPktSDES(boolean reportThisSession, RTPSession rtpSession, Participant[] additionalParticipants) {
-		super.packetType = 202;
-		// Fetch all the right stuff from the database
-		reportSelf = reportThisSession;
-		participants = additionalParticipants;
-		this.rtpSession = rtpSession; 
-	}
-	
-	/**
-	 * Constructor that parses a received packet
-	 * 
-	 * @param aRawPkt the byte[] containing the packet
-	 * @param start where in the byte[] this packet starts
-	 * @param socket the address from which the packet was received
-	 * @param partDb the participant database
-	 */
-	protected RtcpPktSDES(byte[] aRawPkt,int start, InetSocketAddress socket, ParticipantDatabase partDb) {
-		if(RTPSession.rtcpDebugLevel > 8) {
-			System.out.println("  -> RtcpPktSDES(byte[], ParticipantDabase)");
-		}
-		rawPkt = aRawPkt;
-
-		if(! super.parseHeaders(start) || packetType != 202 ) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktSDES.parseHeaders() etc. problem");
-			}
-			super.problem = -202;
-		} else {
-			//System.out.println(" DECODE SIZE: " + super.length + " itemcount " + itemCount );
-			
-			int curPos = 4 + start;
-			int curLength;
-			int curType;
-			long ssrc;
-			boolean endReached = false;
-			boolean newPart;
-			this.participants = new Participant[itemCount];
-			
-			// Loop over SSRC SDES chunks
-			for(int i=0; i< itemCount; i++) {
-				ssrc = StaticProcs.bytesToUIntLong(aRawPkt, curPos);
-				Participant part = partDb.getParticipant(ssrc);
-				if(part == null) {
-					if(RTPSession.rtcpDebugLevel > 1) {
-						System.out.println("RtcpPktSDES(byte[], ParticipantDabase) adding new participant, ssrc:"+ssrc+" "+socket);
-					}
-					
-					part = new Participant(socket, socket , ssrc);
-					newPart = true;
-				} else {
-					newPart = false;
-				}
-				
-				curPos += 4;
-							
-				//System.out.println("PRE endReached " + endReached + " curPos: " + curPos + " length:" + this.length + (!endReached && (curPos/4) < this.length));
-				
-				while(!endReached && (curPos/4) <= this.length) {
-					//System.out.println("endReached " + endReached + " curPos: " + curPos + " length:" + this.length);
-					curType = (int) aRawPkt[curPos];
-					
-					if(curType == 0) {	
-						curPos += 4 - (curPos % 4);
-						endReached = true;
-					} else {
-						curLength  = (int) aRawPkt[curPos + 1];
-						//System.out.println("curPos:"+curPos+" curType:"+curType+" curLength:"+curLength+" read from:"+(curPos + 1));
-
-						if(curLength > 0) {
-							byte[] item = new byte[curLength];
-							//System.out.println("curPos:"+curPos+" arawPkt.length:"+aRawPkt.length+" curLength:"+curLength);
-							System.arraycopy(aRawPkt, curPos + 2, item, 0, curLength);
-							
-							switch(curType) {
-							case 1:  part.cname = new String(item); break;
-							case 2:  part.name = new String(item); break;
-							case 3:  part.email = new String(item); break;
-							case 4:  part.phone = new String(item); break;
-							case 5:  part.loc = new String(item); break;
-							case 6:  part.tool = new String(item); break;
-							case 7:  part.note = new String(item); break;
-							case 8:  part.priv = new String(item); break;
-							}
-							//System.out.println("TYPE " + curType + " value:" + new String(item) );
-							
-						} else {
-							switch(curType) {
-							case 1:  part.cname = null; break;
-							case 2:  part.name = null; break;
-							case 3:  part.email = null; break;
-							case 4:  part.phone = null; break;
-							case 5:  part.loc = null; break;
-							case 6:  part.tool = null; break;
-							case 7:  part.note = null; break;
-							case 8:  part.priv = null; break;
-							}
-							
-						}
-						curPos = curPos + curLength + 2;
-					}
-				}
-				
-				// Save the participant
-				this.participants[i] = part;
-				if(newPart)
-					partDb.addParticipant(2,part);
-				
-				//System.out.println("HEPPPPPP " + participants[i].cname );
-			}
-		}
-		if(RTPSession.rtcpDebugLevel > 8) {
-			System.out.println("  <- RtcpPktSDES()");
-		}
-	}
-
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {	
-		byte[] temp = new byte[1450];
-		byte[] someBytes = StaticProcs.uIntLongToByteWord(this.rtpSession.ssrc);
-		System.arraycopy(someBytes, 0, temp, 4, 4);
-		int pos = 8;
-	
-		String tmpString = null;
-		for(int i=1; i<9;i++) {			
-			switch(i) {
-				case 1:  tmpString = this.rtpSession.cname; break;
-				case 2:  tmpString = this.rtpSession.name; break;
-				case 3:  tmpString = this.rtpSession.email; break;
-				case 4:  tmpString = this.rtpSession.phone; break;
-				case 5:  tmpString = this.rtpSession.loc; break;
-				case 6:  tmpString = this.rtpSession.tool; break;
-				case 7:  tmpString = this.rtpSession.note; break;
-				case 8:  tmpString = this.rtpSession.priv; break;
-			}
-			
-			if(tmpString != null) {
-				someBytes = tmpString.getBytes();
-				temp[pos] = (byte) i;
-				temp[pos+1] = (byte) someBytes.length;
-				System.arraycopy(someBytes, 0, temp, pos + 2, someBytes.length);
-				//System.out.println("i: "+i+" pos:"+pos+" someBytes.length:"+someBytes.length);
-				pos = pos + someBytes.length + 2;
-				//if(i == 1 ) {
-				//	System.out.println("trueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + tmpString);
-				//}
-			}
-		}
-		int leftover = pos % 4;
-		if(leftover == 1) {
-			temp[pos] = (byte) 0; 
-			temp[pos + 1] = (byte) 1; 
-			pos += 3;
-		} else if(leftover == 2) {
-			temp[pos] = (byte) 0; 
-			temp[pos + 1] = (byte) 0; 
-			pos += 2;
-		} else if(leftover == 3) {
-			temp[pos] = (byte) 0; 
-			temp[pos + 1] = (byte) 3; 
-			pos += 5;
-		}
-		
-		// TODO Here we ought to loop over participants, if we're doing SDES for other participants.
-		
-		super.rawPkt = new byte[pos];
-		itemCount = 1;
-		//This looks wrong, but appears to be fine..
-		System.arraycopy(temp, 0, super.rawPkt, 0, pos);
-		writeHeaders();
-	}
-	
-	/**
-	 * Debug purposes only
-	 */
-	public void debugPrint() {
-		System.out.println("RtcpPktSDES.debugPrint() ");
-		if(participants != null) {
-			for(int i= 0; i<participants.length; i++) {
-				Participant part = participants[i];
-				System.out.println("     part.ssrc: " + part.ssrc + "  part.cname: " + part.cname + " part.loc: " + part.loc);
-			}
-		} else {
-			System.out.println("     nothing to report (only valid for received packets)");
-		}
-	}
-}
--- a/src/jlibrtp/RtcpPktSR.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RTCP packets for Sender Reports 
- * 
- * @author Arne Kepp
- */
-public class RtcpPktSR extends RtcpPkt {
-	/** NTP timestamp, MSB */
-	protected long ntpTs1 = -1; //32 bits
-	/** NTP timestamp, LSB */
-	protected long ntpTs2 = -1; //32 bits
-	/** RTP timestamp */
-	protected long rtpTs = -1; //32 bits
-	/** Senders packet count */
-	protected long sendersPktCount = -1; //32 bits
-	/** Senders octet count */
-	protected long sendersOctCount = -1; //32 bits
-	/** RR packet with receiver reports that we can append */
-	protected RtcpPktRR rReports = null;
-	
-	/**
-	 * Constructor for a new Sender Report packet
-	 * 
-	 * @param ssrc the senders SSRC, presumably from RTPSession
-	 * @param pktCount packets sent in this session
-	 * @param octCount octets sent in this session
-	 * @param rReports receiver reports, as RR packets, to be included in this packet
-	 */
-	protected RtcpPktSR(long ssrc, long pktCount, long octCount, RtcpPktRR rReports) {
-		// Fetch all the right stuff from the database
-		super.ssrc = ssrc;
-		super.packetType = 200;
-		sendersPktCount = pktCount;
-		sendersOctCount = octCount;
-		this.rReports = rReports;
-	}
-	
-	/**
-	 * Constructor that parses a received packet
-	 * 
-	 * @param aRawPkt the raw packet
-	 * @param start the position at which SR starts
-	 * @param length used to determine number of included receiver reports
-	 */
-	protected RtcpPktSR(byte[] aRawPkt, int start, int length) {
-		if(RTPSession.rtpDebugLevel > 9) {
-				System.out.println("  -> RtcpPktSR(rawPkt)");
-		}
-		
-		super.rawPkt = aRawPkt;
-
-		if(!super.parseHeaders(start) || packetType != 200 ) {
-			if(RTPSession.rtpDebugLevel > 2) {
-				System.out.println(" <-> RtcpPktSR.parseHeaders() etc. problem: "+ (!super.parseHeaders(start) ) + " " + packetType + " " + super.length);
-			}
-			super.problem = -200;
-		} else {
-			super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4+start);
-			if(length > 11)
-				ntpTs1 = StaticProcs.bytesToUIntLong(aRawPkt,8+start);
-			if(length > 15)
-				ntpTs2 = StaticProcs.bytesToUIntLong(aRawPkt,12+start);
-			if(length > 19)
-				rtpTs = StaticProcs.bytesToUIntLong(aRawPkt,16+start);
-			if(length > 23)
-				sendersPktCount = StaticProcs.bytesToUIntLong(aRawPkt,20+start);
-			if(length > 27)
-				sendersOctCount = StaticProcs.bytesToUIntLong(aRawPkt,24+start);
-			
-			// RRs attached?
-			if(itemCount > 0) {
-				rReports = new RtcpPktRR(rawPkt,start,itemCount);
-			}
-		}
-		
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println("  <- RtcpPktSR(rawPkt)");
-		}
-	}
-	
-	/**
-	 * Encode the packet into a byte[], saved in .rawPkt
-	 * 
-	 * CompRtcpPkt will call this automatically
-	 */
-	protected void encode() {		
-		if(RTPSession.rtpDebugLevel > 9) {
-			if(this.rReports != null) {
-				System.out.println("  -> RtcpPktSR.encode() receptionReports.length: " + this.rReports.length );
-			} else {
-				System.out.println("  -> RtcpPktSR.encode() receptionReports: null");
-			}
-		}
-		
-		if(this.rReports != null) {
-			super.itemCount = this.rReports.reportees.length;
-						
-			byte[] tmp = this.rReports.encodeRR();
-			super.rawPkt = new byte[tmp.length+28];
-			//super.length = (super.rawPkt.length / 4) - 1;
-			
-			System.arraycopy(tmp, 0, super.rawPkt, 28, tmp.length);
-			
-		} else {
-			super.itemCount = 0;
-			super.rawPkt = new byte[28];
-			//super.length = 6;
-		}
-		//Write the common header
-		super.writeHeaders();
-		
-		// Convert to NTP and chop up
-		long timeNow = System.currentTimeMillis();
-		ntpTs1 = 2208988800L + (timeNow/1000);
-		long ms = timeNow % 1000;
-		double tmp = ((double)ms) / 1000.0;
-		tmp = tmp * (double)4294967295L;
-		ntpTs2 = (long) tmp;
-		rtpTs = System.currentTimeMillis();
-		
-		//Write SR stuff
-		byte[] someBytes;
-		someBytes = StaticProcs.uIntLongToByteWord(super.ssrc);
-		System.arraycopy(someBytes, 0, super.rawPkt, 4, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(ntpTs1);
-		System.arraycopy(someBytes, 0, super.rawPkt, 8, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(ntpTs2);
-		System.arraycopy(someBytes, 0, super.rawPkt, 12, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(rtpTs);
-		System.arraycopy(someBytes, 0, super.rawPkt, 16, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(sendersPktCount);
-		System.arraycopy(someBytes, 0, super.rawPkt, 20, 4);
-		someBytes = StaticProcs.uIntLongToByteWord(sendersOctCount);
-		System.arraycopy(someBytes, 0, super.rawPkt, 24, 4);
-		
-		if(RTPSession.rtpDebugLevel > 9) {
-			System.out.println("  <- RtcpPktSR.encode() ntpTs1: "
-					+ Long.toString(ntpTs1) + " ntpTs2: " + Long.toString(ntpTs2));
-		}
-	}
-
-	/**
-	 * Debug purposes only
-	 */
-	public void debugPrint() {
-		System.out.println("RtcpPktSR.debugPrint() ");
-		System.out.println("  SSRC:"+Long.toString(super.ssrc) +" ntpTs1:"+Long.toString(ntpTs1)
-				+" ntpTS2:"+Long.toString(ntpTs2)+" rtpTS:"+Long.toString(rtpTs)
-				+" senderPktCount:"+Long.toString(sendersPktCount)+" sendersOctetCount:"
-				+Long.toString(sendersOctCount));
-		if(this.rReports != null) {
-			System.out.print("  Part of Sender Report: ");	
-			this.rReports.debugPrint();
-			System.out.println("  End Sender Report");
-		} else {
-			System.out.println("No Receiver Reports associated with this Sender Report.");
-		}
-	}
-}
--- a/src/jlibrtp/RtpPkt.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,370 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/**
- * RtpPkt is the basic class for creating and parsing RTP packets.
- * 
- * There are two ways of instantiating an RtpPkt. One is for packets that you wish to send,
- * which requires that you provide basic information about the packet and a payload. Upon calling
- * encode() the fields of the structure are written into a bytebuffer, in the form that it would
- * sent across the network, excluding the UDP headers.
- * 
- * The other way is by passing a bytebuffer. The assumption is that this is a packet
- * that has been received from the network, excluding UDP headers, and the bytebuffer will
- * be parsed into the correct fields. 
- * 
- * The class keeps track of changes. Therefore, modifications are possible after calling encode(),
- * if necessary, the raw version of the packet will be regenerated on subsequent requests.
- * 
- * @author Arne Kepp
- */
-public class RtpPkt {
-	/** Whether the packet has been changed since encode() */
-	private boolean rawPktCurrent = false;
-	/** The version, always 2, 2 bits */
-	private int version = 2; 		//2 bits
-	/** Whether the packet is padded, 1 bit */
-	private int padding; 			//1 bit
-	/** Whether and extension is used, 1 bit */
-	private int extension = 0; 		//1 bit
-	/** Whether the packet is marked, 1 bit */
-	private int marker = 0;			//1 bit
-	/** What payload type is used, 7 bits */
-	private int payloadType;		//
-	/** The sequence number, taken from RTP Session, 16 bits */
-	private int seqNumber;			//16 bits
-	/** The RTP timestamp, 32bits */
-	private long timeStamp;			//32 bits
-	/** The SSRC of the packet sender, 32 bits*/
-	private long ssrc;				//32 bits
-	/** SSRCs of contributing sources, 32xn bits, n<16 */ 
-	private long[] csrcArray = null;//
-	
-	/** Contains the actual data (eventually) */
-	private byte[] rawPkt = null;
-	/** The actual data, without any RTP stuff */
-	private byte[] payload = null;
-
-	/**
-	 * Construct a packet-instance. The ByteBuffer required for UDP transmission can afterwards be obtained from getRawPkt(). If you need to set additional parameters, such as the marker bit or contributing sources, you should do so before calling getRawPkt;
-	 *
-	 * @param aTimeStamp RTP timestamp for data
-	 * @param syncSource the SSRC, usually taken from RTPSession
-	 * @param seqNum Sequency number
-	 * @param plt Type of payload
-	 * @param pl Payload, the actual data
-	 */
-	protected RtpPkt(long aTimeStamp, long syncSource, int seqNum, int plt, byte[] pl){
-		int test = 0;
-		test += setTimeStamp(aTimeStamp);
-		test += setSsrc(syncSource);
-		test += setSeqNumber(seqNum);
-		test += setPayloadType(plt);
-		test += setPayload(pl);
-		if(test != 0) {
-			System.out.println("RtpPkt() failed, check with checkPkt()");
-		}
-		rawPktCurrent = true;
-		if( RTPSession.rtpDebugLevel > 5) {
-			System.out.println("<--> RtpPkt(aTimeStamp, syncSource, seqNum, plt, pl)"); 
-		}
-	}
-	/**
-	 * Construct a packet-instance from an raw packet (believed to be RTP). The UDP-headers must be removed before invoking this method. Call checkPkt on the instance to verify that it was successfully parsed.
-	 *
-	 * @param aRawPkt The data-part of a UDP-packet believed to be RTP 
-	 * @param packetSize the number of valid octets in the packet, should be aRawPkt.length
-	 */
-	protected RtpPkt(byte[] aRawPkt, int packetSize){
-		if( RTPSession.rtpDebugLevel > 5) {
-			System.out.println("-> RtpPkt(aRawPkt)"); 
-		}
-		//Check size, need to have at least a complete header
-		if(aRawPkt == null) {
-			System.out.println("RtpPkt(byte[]) Packet null");
-		}
-		
-		int remOct = packetSize - 12;
-		if(remOct >= 0) {
-			rawPkt = aRawPkt;	//Store it
-			//Interrogate the packet
-			sliceFirstLine();
-			if(version == 2) {
-				sliceTimeStamp();
-				sliceSSRC();
-				if(remOct > 4 && getCsrcCount() > 0) {
-					sliceCSRCs();
-					remOct -= csrcArray.length * 4; //4 octets per CSRC
-				}
-				// TODO Extension
-				if(remOct > 0) {
-					slicePayload(remOct);
-				}
-			
-				//Sanity checks
-				checkPkt();
-		
-				//Mark the buffer as current
-				rawPktCurrent = true;
-			} else {
-				System.out.println("RtpPkt(byte[]) Packet is not version 2, giving up.");
-			}
-		} else {
-			System.out.println("RtpPkt(byte[]) Packet too small to be sliced");
-		}
-		rawPktCurrent = true;
-		if( RTPSession.rtpDebugLevel > 5) {
-			System.out.println("<- RtpPkt(aRawPkt)");
-		}
-	}
-	
-	/*********************************************************************************************************
-	 *                                                Reading stuff 
-	 *********************************************************************************************************/
-	protected int checkPkt() {
-		//TODO, check for version 2 etc
-		return 0;
-	}
-	protected int getHeaderLength() {
-		//TODO include extension
-		return 12 + 4*getCsrcCount();
-	}
-	protected int getPayloadLength() {
-		return payload.length;
-	}
-	//public int getPaddingLength() {
-	//	return lenPadding;
-	//}
-	protected int getVersion() {
-		return version;
-	}
-	//public boolean isPadded() {
-	//	if(lenPadding > 0) {
-	//		return true;
-	//	}else {
-	//		return false;
-	//	}
-	//}
-	//public int getHeaderExtension() {
-	//TODO
-	//}
-	protected boolean isMarked() {
-		return (marker != 0);
-	}
-	protected int getPayloadType() {
-		return payloadType;
-	}
-	
-	protected int getSeqNumber() {
-		return seqNumber;
-	}
-	protected long getTimeStamp() {
-		return timeStamp;
-	}
-	protected long getSsrc() {
-		return ssrc;
-	}
-	
-	protected int getCsrcCount() {
-		if(csrcArray != null) {
-			return csrcArray.length;
-		}else{
-			return 0;
-		}
-	}
-	protected long[] getCsrcArray() {
-		return csrcArray;
-	}
-
-	/** 
-	 *  Encodes the a
-	 */
-	protected byte[] encode() {
-		if(! rawPktCurrent || rawPkt == null) {
-			writePkt();
-		} 
-		return rawPkt;
-	}
-	
-	/* For debugging purposes */
-	protected void printPkt() {
-		System.out.print("V:" + version + " P:" + padding + " EXT:" + extension);
-		System.out.println(" CC:" + getCsrcCount() + " M:"+ marker +" PT:" + payloadType + " SN: "+ seqNumber);
-		System.out.println("Timestamp:" + timeStamp + "(long output as int, may be 2s complement)");
-		System.out.println("SSRC:" + ssrc + "(long output as int, may be 2s complement)");
-		for(int i=0;i<getCsrcCount();i++) {
-			System.out.println("CSRC:" + csrcArray[i] + "(long output as int, may be 2s complement)");
-		}
-		//TODO Extension
-		System.out.println("Payload, first four bytes: " + payload[0] + " " + payload[1] + " " + payload[2] + " " + payload[3]);
-	}
-	/*********************************************************************************************************
-	 *                                                Setting stuff 
-	 *********************************************************************************************************/
-	protected void setMarked(boolean mark) {
-		rawPktCurrent = false;
-		if(mark) {
-			marker = 1;
-		} else {
-			marker = 0;
-		}
-	}
-	//public int setHeaderExtension() {
-	//TODO
-	//}	
-	protected int setPayloadType(int plType) {
-		int temp = (plType & 0x0000007F); // 7 bits, checks in RTPSession as well.
-		if(temp == plType) {
-			rawPktCurrent = false;
-			payloadType = temp;
-			return 0;
-		} else {
-			return -1;
-		}
-	}
-	
-	protected int setSeqNumber(int number) {
-		if(number <= 65536 && number >= 0) {
-			rawPktCurrent = false;
-			seqNumber = number;
-			return 0;
-		} else {
-			System.out.println("RtpPkt.setSeqNumber: invalid number");
-			return -1;
-		}
-	}
-	
-	protected int setTimeStamp(long time) {
-		rawPktCurrent = false;
-		timeStamp = time;
-		return 0;	//Naive for now
-	}
-	
-	protected int setSsrc(long source) {
-		rawPktCurrent = false;
-		ssrc = source;
-		return 0;	//Naive for now
-	}
-	
-	protected int setCsrcs(long[] contributors) {
-		if(contributors.length <= 16) {
-			csrcArray = contributors;
-			return 0;
-		} else {
-			System.out.println("RtpPkt.setCsrcs: Cannot have more than 16 CSRCs");
-			return -1;
-		}
-	}
-	
-	protected int setPayload(byte[] data) {
-		// TODO Padding
-		if(data.length < (1500 - 12)) {
-			rawPktCurrent = false;
-			payload = data;
-			return 0;
-		} else {
-			System.out.println("RtpPkt.setPayload: Cannot carry more than 1480 bytes for now.");
-			return -1;
-		}
-	}
-	protected byte[] getPayload() {
-		return payload;
-	}
-
-	/*********************************************************************************************************
-	 *                                           Private functions 
-	 *********************************************************************************************************/
-	//Generate a bytebyffer representing the packet, store it.
-	private void writePkt() {
-		int bytes = getPayloadLength();
-		int headerLen = getHeaderLength();
-		int csrcLen = getCsrcCount();
-		rawPkt = new byte[headerLen + bytes];
-		
-		// The first line contains, version and various bits
-		writeFirstLine();
-		byte[] someBytes = StaticProcs.uIntLongToByteWord(timeStamp);
-		for(int i=0;i<4;i++) {
-			rawPkt[i + 4] = someBytes[i];
-		}
-		//System.out.println("writePkt timeStamp:" + rawPkt[7]);
-		
-		someBytes = StaticProcs.uIntLongToByteWord(ssrc);
-		System.arraycopy(someBytes, 0, rawPkt, 8, 4);
-		//System.out.println("writePkt ssrc:" + rawPkt[11]);
-		
-		for(int i=0; i<csrcLen ; i++) {
-			someBytes = StaticProcs.uIntLongToByteWord(csrcArray[i]);
-			System.arraycopy(someBytes, 0, rawPkt, 12 + 4*i, 4);
-		}
-		// TODO Extension
-
-		//Payload
-		System.arraycopy(payload, 0, rawPkt, headerLen, bytes);
-		rawPktCurrent = true;
-	}
-	//Writes the first 4 octets of the RTP packet
-	private void writeFirstLine() {
-		byte aByte = 0;
-		aByte |=(version << 6);
-		aByte |=(padding << 5);
-		aByte |=(extension << 4);
-		aByte |=(getCsrcCount());
-		rawPkt[0] = aByte;
-		aByte = 0;
-		aByte |=(marker << 7);
-		aByte |= payloadType;
-		rawPkt[1] = aByte;
-		byte[] someBytes = StaticProcs.uIntIntToByteWord(seqNumber);
-		rawPkt[2] = someBytes[0];
-		rawPkt[3] = someBytes[1];
-	}
-	//Picks apart the first 4 octets of an RTP packet
-	private void sliceFirstLine() {
-		version = ((rawPkt[0] & 0xC0) >>> 6);
-		padding = ((rawPkt[0] & 0x20) >>> 5);
-		extension = ((rawPkt[0] & 0x10) >>> 4);
-		csrcArray = new long[(rawPkt[0] & 0x0F)];
-		marker = ((rawPkt[1] & 0x80) >> 7);
-		payloadType = (rawPkt[1] & 0x7F);
-		seqNumber = StaticProcs.bytesToUIntInt(rawPkt, 2);
-	}
-	//Takes the 4 octets representing the timestamp
-	private void sliceTimeStamp() {
-		timeStamp = StaticProcs.bytesToUIntLong(rawPkt, 4);
-	}
-	//Takes the 4 octets representing the SSRC
-	private void sliceSSRC() {
-		ssrc = StaticProcs.bytesToUIntLong(rawPkt,8);
-	}
-	//Check the length of the csrcArray (set during sliceFirstLine) 
-	private void  sliceCSRCs() {
-		for(int i=0; i< csrcArray.length; i++) {
-			ssrc = StaticProcs.bytesToUIntLong(rawPkt, i*4 + 12);
-		}
-	}
-	//Extensions //TODO
-	private void slicePayload(int bytes) {
-		payload = new byte[bytes];
-		int headerLen = getHeaderLength();
-		
-		System.arraycopy(rawPkt, headerLen, payload, 0, bytes);
-	}
-}	
\ No newline at end of file
--- a/src/jlibrtp/StaticProcs.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-/** 
- * Generic functions for converting between unsigned integers and byte[]s.
- *
- * @author Arne Kepp
- */
-public class StaticProcs {
-
-	/** 
-	 * Converts an integer into an array of bytes. 
-	 * Primarily used for 16 bit unsigned integers, ignore the first two octets.
-	 * 
-	 * @param i a 16 bit unsigned integer in an int
-	 * @return byte[2] representing the integer as unsigned, most significant bit first. 
-	 */
-	public static byte[] uIntIntToByteWord(int i) {		
-		byte[] byteWord = new byte[2];
-		byteWord[0] = (byte) ((i >> 8) & 0x000000FF);
-		byteWord[1] = (byte) (i & 0x00FF);
-		return byteWord;
-	}
-	
-	/** 
-	 * Converts an unsigned 32 bit integer, stored in a long, into an array of bytes.
-	 * 
-	 * @param j a long
-	 * @return byte[4] representing the unsigned integer, most significant bit first. 
-	 */
-	public static byte[] uIntLongToByteWord(long j) {
-		int i = (int) j;
-		byte[] byteWord = new byte[4];
-		byteWord[0] = (byte) ((i >>> 24) & 0x000000FF);
-		byteWord[1] = (byte) ((i >> 16) & 0x000000FF);
-		byteWord[2] = (byte) ((i >> 8) & 0x000000FF);
-		byteWord[3] = (byte) (i & 0x00FF);
-		return byteWord;
-	}
-	
-	/** 
-	 * Combines two bytes (most significant bit first) into a 16 bit unsigned integer.
-	 * 
-	 * @param index of most significant byte
-	 * @return int with the 16 bit unsigned integer
-	 */
-	public static int bytesToUIntInt(byte[] bytes, int index) {
-		int accum = 0;
-		int i = 1;
-		for (int shiftBy = 0; shiftBy < 16; shiftBy += 8 ) {
-			accum |= ( (long)( bytes[index + i] & 0xff ) ) << shiftBy;
-			i--;
-		}
-		return accum;
-	}
-	
-	/** 
-	 * Combines four bytes (most significant bit first) into a 32 bit unsigned integer.
-	 * 
-	 * @param bytes
-	 * @param index of most significant byte
-	 * @return long with the 32 bit unsigned integer
-	 */
-	public static long bytesToUIntLong(byte[] bytes, int index) {
-		long accum = 0;
-		int i = 3;
-		for (int shiftBy = 0; shiftBy < 32; shiftBy += 8 ) {
-			accum |= ( (long)( bytes[index + i] & 0xff ) ) << shiftBy;
-			i--;
-		}
-		return accum;
-	}
-	
-	/**
-	 * Converts an arbitrary number of bytes, assumed to represent an unsigned integer,
-	 * to a Java long
-	 */
-	/*public static long bytesToUintLong(byte[] bytes, int firstByte, int lastByte) {
-		long accum = 0;
-		int i = lastByte - firstByte;
-		if(i > 7) {
-			System.out.println("!!!! StaticProcs.bytesToUintLong() Can't convert more than 63 bits!");
-			return -1;
-		}
-		int stop = (i+1)*8;
-		
-		for (int shiftBy = 0; shiftBy < stop; shiftBy += 8 ) {
-			accum |= ( (long)( bytes[firstByte + i] & 0xff ) ) << shiftBy;
-			i--;
-		}
-		return accum;
-	}*/
-	
-	/**
-	 * Converts an arbitrary number of bytes, assumed to represent an unsigned integer,
-	 * to a Java int
-	 */
-	/*	public static int bytesToUintInt(byte[] bytes, int firstByte, int lastByte) {
-		int accum = 0;
-		int i = lastByte - firstByte;
-		if(i > 3) {
-			System.out.println("!!!! StaticProcs.bytesToUintLong() Can't convert more than 31 bits!");
-			return -1;
-		}
-		int stop = (i+1)*8;
-		
-		for (int shiftBy = 0; shiftBy < stop; shiftBy += 8 ) {
-			accum |= ( (long)( bytes[firstByte + i] & 0xff ) ) << shiftBy;
-			i--;
-		}
-		return accum;
-	}*/
-	
-	/**
-	 * Recreates a UNIX timestamp based on the NTP representation used
-	 * in RTCP SR packets
-	 * 
-	 * @param ntpTs1 from RTCP SR packet
-	 * @param ntpTs2 from RTCP SR packet
-	 * @return the UNIX timestamp
-	 */
-	public static long undoNtpMess(long ntpTs1, long ntpTs2) {		
-		long timeVal = (ntpTs1 - 2208988800L)*1000;
-			
-		double tmp = (1000.0*(double)ntpTs2)/((double)4294967295L);
-		long ms = (long) tmp;
-		//System.out.println(" timeVal: " +Long.toString(timeVal)+ " ms " + Long.toString(ms));
-		timeVal += ms;
-		
-		return timeVal;
-	}
-	
-
-	
-	/** 
-	 * Get the bits of a byte
-	 * 
-	 * @param aByte the byte you wish to convert
-	 * @return a String of 1's and 0's
-	 */
-	public static String bitsOfByte(byte aByte) {
-		int temp;
-		String out = "";
-		for(int i=7; i>=0; i--) {
-			temp = (aByte >>> i);
-			temp &= 0x0001;
-			out += (""+temp);
-		}
-		return out;
-	}
-	
-	/** 
-	 * Get the hex representation of a byte
-	 * 
-	 * @param aByte the byte you wish to convert
-	 * @return a String of two chars 0-1,A-F
-	 */
-	public static String hexOfByte(byte aByte) {
-		String out = "";
-
-		for(int i=0; i<2; i++) {
-			int temp = (int) aByte;
-			if(temp < 0) {
-				temp +=256;
-			}
-			if(i == 0) {
-				temp = temp/16;
-			} else {
-				temp = temp%16;
-			}
-			
-			if( temp > 9) {
-				switch(temp) {
-				case 10: out += "A"; break;
-				case 11: out += "B"; break;
-				case 12: out += "C"; break;
-				case 13: out += "D"; break;
-				case 14: out += "E"; break;
-				case 15: out += "F"; break;
-				}
-			} else {
-				out += Integer.toString(temp);
-			}
-		}
-		return out;
-	}
-	
-	/** 
-	 * Get the hex representation of a byte
-	 * 
-	 * @param hex 4 bytes  the byte you wish to convert
-	 * @return a String of two chars 0-1,A-F
-	 */
-	public static byte byteOfHex(byte[] hex) {
-		byte retByte = 0;
-		Byte tmp;
-		int val = 0;
-		
-		// First 4 bits
-		tmp = hex[0];
-		val = tmp.intValue();
-		if(val > 64) {
-			// Letter
-			val -= 55;
-		} else {
-			// Number
-			val -= 48;
-		}
-		retByte = ((byte) (val << 4));
-		
-		// Last 4 bits
-		tmp = hex[1];
-		val = tmp.intValue();
-		if(val > 64) {
-			// Letter
-			val -= 55;
-		} else {
-			// Number
-			val -= 48;
-		}
-		retByte |= ((byte) val);
-		
-		return retByte;
-	}
-	
-	
-	/** 
-	 * Print the bits of a byte to standard out. For debugging.
-	 * 
-	 * @param aByte the byte you wish to print out.
-	 */
-	public static void printBits(byte aByte) {
-		int temp;
-		for(int i=7; i>=0; i--) {
-			temp = (aByte >>> i);
-			temp &= 0x0001;
-			System.out.print(""+temp);
-		}
-		System.out.println();
-	}
-	
-	public static String bitsOfBytes(byte[] bytes) {
-		String str = "";
-		//Expensive, but who cares
-		for(int i=0; i<bytes.length; i++ ) {
-			str += bitsOfByte(bytes[i]) + " ";
-			if((i + 1) % 4 == 0)
-				str += "\n";
-		}
-		
-		return str;
-	}
-}
\ No newline at end of file
--- a/src/jlibrtp/ValidateParticipantDatabase.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-
-public class ValidateParticipantDatabase {
-
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		DatagramSocket rtpSocket = null;
-		DatagramSocket rtcpSocket = null;
-		try {
-			rtpSocket = new DatagramSocket(6002);
-			rtcpSocket = new DatagramSocket(6003);
-		} catch (Exception e) {
-			System.out.println("RTPSession failed to obtain port");
-		}
-		RTPSession rtpSession = new RTPSession(rtpSocket, rtcpSocket);
-		
-		ParticipantDatabase partDb = new ParticipantDatabase(rtpSession);
-		
-		Participant part0 = new Participant("127.0.0.1", 4545, 4555);
-		Participant part1 = new Participant("127.0.0.1", 4546, 4556);
-		Participant part2 = new Participant("127.0.0.1", 4547, 4556);
-		
-		partDb.addParticipant(0,part0);
-		partDb.addParticipant(0,part1);
-		partDb.addParticipant(0,part2);
-		
-		partDb.debugPrint();
-		
-		System.out.println("********************* Removing Participant 1 (4546) ***********************");
-		partDb.removeParticipant(part1);
-		partDb.debugPrint();
-
-		
-		InetAddress inetAdr = null;
-		try { inetAdr = InetAddress.getByName("127.0.0.1"); } catch (Exception e) { };
-		
-		//Participant part3 = partDb.getParticipant(inetAdr);
-		//part3.ssrc = 12345678;
-		System.out.println("********************* Updating Participant 3 (4546) ***********************");
-		//partDb.updateParticipant(part3);
-		
-		partDb.debugPrint();
-	}
-
-}
--- a/src/jlibrtp/ValidatePktBuffer.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.net.DatagramSocket;
-
-
-/**
- * Validates the PktBuffer and associated classes.
- * 
- * @author Arne Kepp
- *
- */
-public class ValidatePktBuffer {
-
-	/**
-	 * Instantiates a buffer, creates some packets, adds them and sorts them.
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		// TODO Auto-generated method stub
-		DatagramSocket rtpSocket = null;
-		DatagramSocket rtcpSocket = null;
-		try {
-			rtpSocket = new DatagramSocket(6002);
-			rtcpSocket = new DatagramSocket(6003);
-		} catch (Exception e) {
-			System.out.println("RTPSession failed to obtain port");
-		}
-		RTPSession rtpSession = new RTPSession(rtpSocket, rtcpSocket);
-		
-		
-		String str1 = "ab";
-		String str2 = "cd";
-		String str3 = "ef";
-		String str4 = "gh";
-		String str5 = "ij";
-		String str6 = "kl";
-		//String str7 = "mn";
-		
-		long syncSource1 = 1;
-		int seqNumber1 = 1;
-		//int seqNumber2 = 1;
-		RtpPkt pkt1 = new RtpPkt(10, syncSource1, 1, 0, str1.getBytes());
-		RtpPkt pkt2 = new RtpPkt(20, syncSource1, 2, 0, str2.getBytes());
-		RtpPkt pkt3 = new RtpPkt(30, syncSource1, 3, 0, str3.getBytes());
-		RtpPkt pkt4 = new RtpPkt(40, syncSource1, 4, 0, str4.getBytes());
-		RtpPkt pkt6 = new RtpPkt(60, syncSource1, 6, 0, str5.getBytes());
-		RtpPkt pkt7 = new RtpPkt(70, syncSource1, 7, 0, str6.getBytes());
-		
-		Participant p = new Participant();
-		
-		PktBuffer pktBuf = new PktBuffer(rtpSession, p, pkt1);
-		pktBuf.addPkt(pkt3); //2
-		pktBuf.addPkt(pkt2); //3
-		DataFrame aFrame = pktBuf.popOldestFrame();
-		String outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 1 Data from first frame: " + outStr + ", should be ab");
-		pktBuf.addPkt(pkt4); //3
-		pktBuf.addPkt(pkt7); //4
-		System.out.println("** 1.5 sixth");		
-		pktBuf.addPkt(pkt6); //5
-		System.out.println("** 2 Duplicate, should be dropped");
-		pktBuf.addPkt(pkt3); //5
-		// Pop second frame
-		aFrame = pktBuf.popOldestFrame(); //4
-		outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 3 Data from second frame: " + outStr + ", should be cd");
-		
-		// Pop third frame
-		aFrame = pktBuf.popOldestFrame(); //3
-		outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 4 Data from third frame: " + outStr + ", should be ef");
-		System.out.println("** 5 pktBuf.getLength is " + pktBuf.getLength() + ", should be 3");
-		
-		System.out.println("** 6 Late arrival, should be dropped");
-		pktBuf.addPkt(pkt2);
-		
-		aFrame = pktBuf.popOldestFrame();
-		outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 7 Data from fourth frame: " + outStr + ", should be gh");
-		
-		aFrame = pktBuf.popOldestFrame();
-		outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 8 Data from fifth frame: " + outStr + ", should be ij");
-
-		aFrame = pktBuf.popOldestFrame();
-		outStr = new String(aFrame.getConcatenatedData());
-		System.out.println("** 9 Data from fifth frame: " + outStr + ", should be kl");
-	}
-
-}
--- a/src/jlibrtp/ValidateRtcpPkt.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-import java.util.*;
-import java.net.*;
-
-public class ValidateRtcpPkt {
-	
-	public static void main(String[] args) {
-		DatagramSocket rtpSock = null;
-		DatagramSocket rtcpSock = null;
-		
-		try {
-			rtpSock = new DatagramSocket(1233);
-			rtcpSock = new DatagramSocket(1234);
-		} catch (Exception e) {
-			//do nothing
-		}
-		RTPSession rtpSession = new RTPSession(rtpSock, rtcpSock);
-		
-		System.out.println("************************** SSRC: " + rtpSession.ssrc + " **************************");
-		ParticipantDatabase partDb = new ParticipantDatabase(rtpSession);
-		//InetAddress test = InetAddress.getByName("127.0.0.1");
-		Participant part1 = new Participant("127.0.0.1",12, 34);
-		Participant part2 = new Participant("127.0.0.2",56, 78);
-		
-		part1.ssrc = 123;
-		part2.ssrc = 345;
-		
-		InetSocketAddress testadr = null;
-		
-		try {
-			testadr = InetSocketAddress.createUnresolved("localhost", 12371);
-		} catch (Exception e) {
-			// Do nothing
-		}
-		
-		part1.cname = "test3";
-		part2.cname = "test2";
-		part1.loc = "1231231231";
-		part2.loc = "Asker";
-		part1.phone = "+452 1231231";
-		part2.phone = "aasdasda.asdasdas";
-		part1.lastSeqNumber = 111;
-		part2.lastSeqNumber = 222;
-		part1.timeStampLSR = 111111;
-		part2.timeStampLSR = 222222;
-		partDb.addParticipant(0,part1);
-		partDb.addParticipant(0,part2);
-		
-		Participant[] partArray = new Participant[2];
-		partArray[0] = part1;
-		partArray[1] = part2;
-
-		RtcpPktRR rrpkt = new RtcpPktRR(partArray,123456789);
-		RtcpPktSR srpkt = new RtcpPktSR(rtpSession.ssrc,12,21,rrpkt);
-		//RtcpPktSR srpkt2 = new RtcpPktSR(rtpSession.ssrc,12,21,null);
-		//rrpkt = new RtcpPktRR(partArray,1234512311);
-		
-		//srpkt.debugPrint();
-		//rrpkt.debugPrint();
-		
-		CompRtcpPkt compkt = new CompRtcpPkt();
-		compkt.addPacket(srpkt);
-		compkt.addPacket(rrpkt);
-		compkt.addPacket(rrpkt);
-		
-		byte[] test2 = compkt.encode();
-		//System.out.print(StaticProcs.bitsOfBytes(test));
-		System.out.println("****************************** DONE ENCODING *******************************");
-		CompRtcpPkt decomppkt = new CompRtcpPkt(test2,test2.length,testadr,rtpSession);
-		System.out.println("****************************** DONE DECODING *******************************");
-		System.out.println("Problem code:" + decomppkt.problem);
-		
-		ListIterator iter = decomppkt.rtcpPkts.listIterator();
-		int i = 0;
-		
-		while(iter.hasNext()) {
-			System.out.println(" i:" + i + " ");
-			i++;
-			
-			Object aPkt = iter.next();
-			if(	aPkt.getClass() == RtcpPktRR.class) {
-				RtcpPktRR pkt = (RtcpPktRR) aPkt;
-				pkt.debugPrint();
-			} else if(aPkt.getClass() == RtcpPktSR.class) {
-				RtcpPktSR pkt = (RtcpPktSR) aPkt;
-				pkt.debugPrint();
-			}
-		} 
-
-		System.out.println("****************************** BYE *******************************");
-		long[] tempArray = {rtpSession.ssrc};
-		byte[] tempReason = "tas".getBytes();
-		RtcpPktBYE byepkt = new RtcpPktBYE(tempArray,tempReason);
-		//byepkt.debugPrint();
-		byepkt.encode();
-		byte[] rawpktbye = byepkt.rawPkt;
-		
-		RtcpPktBYE byepkt2 = new RtcpPktBYE(rawpktbye,0);
-		byepkt2.debugPrint();
-		
-		System.out.println("****************************** SDES *******************************");
-		RtcpPktSDES sdespkt = new RtcpPktSDES(true,rtpSession,null);
-		rtpSession.cname = "cname123@localhost";
-		//rtpSession.loc = "right here";
-		sdespkt.encode();
-		//rtpSession.cname = "cname124@localhost";
-		//rtpSession.loc = "right hera";
-		byte[] rawpktsdes = sdespkt.rawPkt;
-		InetSocketAddress tmpAdr = (InetSocketAddress) rtpSock.getLocalSocketAddress();
-		RtcpPktSDES decsdespkt = new RtcpPktSDES(rawpktsdes, 0, (InetSocketAddress) rtpSock.getLocalSocketAddress() , partDb);
-		decsdespkt.debugPrint();
-		//partDb.debugPrint();
-		
-		CompRtcpPkt compkt2 = new CompRtcpPkt();
-		compkt2.addPacket(srpkt);
-		compkt2.addPacket(sdespkt);
-		byte[] compkt2Raw = compkt.encode();
-		
-		CompRtcpPkt compkt3 = new CompRtcpPkt(compkt2Raw,compkt2Raw.length,tmpAdr,rtpSession);
-	}
-}
--- a/src/jlibrtp/ValidateStaticProcs.java	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/**
- * Java RTP Library (jlibrtp)
- * Copyright (C) 2006 Arne Kepp
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-package jlibrtp;
-
-
-/**
- * Validates the StaticProcs.
- * 
- * @author Arne Kepp
- *
- */
-public class ValidateStaticProcs {
-
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		// TODO Auto-generated method stub
-		long one = 100;
-		long two = 1;
-		long three = 9999000;
-		
-		byte aByte = (byte) 7;
-		System.out.println("aByte.hex: " + StaticProcs.hexOfByte(aByte));
-			
-		//byte[] oneb = StaticProcs.longToByteWord(one);
-		byte[] twob = StaticProcs.uIntLongToByteWord(two);
-		//byte[] threeb = StaticProcs.longToByteWord(three);
-		
-		for(int i = 0; i< 4; i++) {
-			StaticProcs.printBits(twob[i]);
-		}
-		//one = StaticProcs.combineBytes(oneb[0], oneb[1], oneb[2], oneb[3]);
-		two = StaticProcs.bytesToUIntLong(twob,0);
-		//three = StaticProcs.combineBytes(threeb[0], threeb[1], threeb[2], threeb[3]);
-		
-		System.out.println("  one " + one + "  two " + two + "  three " + three);
-		
-		twob = StaticProcs.uIntLongToByteWord(two);
-		
-		for(int i = 0; i< 4; i++) {
-			StaticProcs.printBits(twob[i]);
-		}
-		
-		byte[] bytes = new byte[2];
-		int check = 0;
-		for(int i=0; i< 65536; i++) {
-			bytes = StaticProcs.uIntIntToByteWord(i);
-			check = StaticProcs.bytesToUIntInt(bytes, 0);
-			if(check != i) {
-				System.out.println(" oops:" + check +" != "+ i);
-				StaticProcs.printBits(bytes[0]);
-				StaticProcs.printBits(bytes[1]);
-			}
-		}
-		int a = 65534;
-		bytes = StaticProcs.uIntIntToByteWord(a);
-		StaticProcs.printBits(bytes[0]);
-		StaticProcs.printBits(bytes[1]);
-		check = StaticProcs.bytesToUIntInt(bytes, 0);
-		System.out.println(check);
-		
-		byte[] arbytes = new byte[22];
-		arbytes[13] = -127;
-		arbytes[14] = 127;
-		arbytes[15] = -1;
-		arbytes[16] = 127;
-		arbytes[17] = -127;
-		System.out.println("arbitrary length:");
-		StaticProcs.printBits(arbytes[14]);
-		StaticProcs.printBits(arbytes[15]);
-		StaticProcs.printBits(arbytes[16]);
-		//long arbTest = StaticProcs.bytesToUintLong(arbytes, 14, 16);
-		//byte[] reArBytes = StaticProcs.uIntLongToByteWord(arbTest);
-		//System.out.println("arbitrary length recode: " + Long.toString(arbTest));
-		//StaticProcs.printBits(reArBytes[0]);
-		//StaticProcs.printBits(reArBytes[1]);
-		//StaticProcs.printBits(reArBytes[2]);
-		//StaticProcs.printBits(reArBytes[3]);
-		
-		byte[] tmp = new byte[4];
-		tmp[0] = -127;
-		tmp[1] = 127;
-		tmp[2] = -49;
-		tmp[3] = -1; 
-		
-		String str2 = "";
-		for(int i=0; i<tmp.length; i++) {
-			str2 += StaticProcs.hexOfByte(tmp[i]);
-		}
-		System.out.println(str2);
-		
-		byte temp2[] = str2.getBytes();
-		byte temp4[] = new byte[temp2.length / 2];
-		byte[] temp3 = new byte[2]; 
-		
-		for(int i=0; i<temp4.length; i++) {
-			temp3[0] = temp2[i*2];
-			temp3[1] = temp2[i*2+1];
-			temp4[i] = StaticProcs.byteOfHex(temp3);
-		}
-		
-		for(int i=0; i<tmp.length; i++) {
-			if(tmp[i] == temp4[i]) {
-				System.out.println("ok");
-			} else {
-				System.out.println("nope");
-			}
-		}
-	}
-}
--- a/src/jlibrtp/package.html	Sat May 23 20:59:27 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<html>
-<body>
-<p>The jlibrtp package contains the core classes of jlibrtp. Most of these classes
- are protected or private, developers looking to use jlibrtp should only concern
- themselves with</p>
- <ul>
- <li>RTPSession - the main session object
- <li>Participant - participant objects
- <li>DataFrame - the containers in which data is returned
- <li>RTPAppIntf - the mininum callback interface
- <li>RTPCAppIntf - optional interface for receing RTCP packets
- <li>RTCPAVPFIntf - optional interface for RTP with feedback
- <li>DebugAppIntf - optional interface for debugging
- </ul>
- <p>
- DebugAppIntf is great for checking network problems and keeping track of packets. 
- If you need extensive debugging you should statically change the debug values in RTPSession.java
- and pay attention to the standard output.
- </p>
- 
-</body>
-</html>
\ No newline at end of file