Index: ereviewboard/org.review_board.ereviewboard.core/.classpath
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/.classpath	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/.classpath	(revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry exported="true" kind="lib" path="lib/objenesis-1.1.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/cloning-1.4.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/json-20080701.jar" sourcepath="lib/json-20080701.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: ereviewboard/org.review_board.ereviewboard.core/.project
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/.project	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/.project	(revision 0)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.review_board.ereviewboard.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.core.prefs	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.core.prefs	(revision 0)
@@ -0,0 +1,265 @@
+#Mon Jul 20 20:16:07 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not 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.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+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=100
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
Index: ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.ui.prefs	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.jdt.ui.prefs	(revision 0)
@@ -0,0 +1,6 @@
+#Mon Jul 20 20:17:07 CEST 2009
+eclipse.preferences.version=1
+formatter_profile=_Java Conventions
+formatter_settings_version=11
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-JSDoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) 2004 - 2009 Mylyn project committers and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n *     Mylyn project committers, Atlassian, Sven Krzyzak\n *******************************************************************************/\n/*******************************************************************************\n * Copyright (c) 2009 Markus Knittig\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the "Software"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions\:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * Contributors\:\n *     Markus Knittig - adapted Trac, Redmine &amp; Atlassian implementations for\n *                      Review Board\n *******************************************************************************/</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="false" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="false" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.php.ui.editor.templates.php.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template></templates>
Index: ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.pde.core.prefs
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.pde.core.prefs	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/.settings/org.eclipse.pde.core.prefs	(revision 0)
@@ -0,0 +1,4 @@
+#Fri Jun 12 15:46:24 CEST 2009
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
Index: ereviewboard/org.review_board.ereviewboard.core/META-INF/MANIFEST.MF
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/META-INF/MANIFEST.MF	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/META-INF/MANIFEST.MF	(revision 0)
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.review_board.ereviewboard.core;singleton:=true
+Bundle-Version: 0.1
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Localization: OSGI-INF/l10n/bundle
+Bundle-Vendor: %Bundle-Vendor
+Bundle-ClassPath: lib/json-20080701.jar,
+ lib/cloning-1.4.jar,
+ lib/objenesis-1.1.jar,
+ .
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.mylyn.tasks.core;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.mylyn.commons.net;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.mylyn.commons.core;bundle-version="[3.2.0,4.0.0)"
+Export-Package: org.review_board.ereviewboard.core,
+ org.review_board.ereviewboard.core.client,
+ org.review_board.ereviewboard.core.exception,
+ org.review_board.ereviewboard.core.model,
+ org.review_board.ereviewboard.core.util
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.review_board.ereviewboard.core.ReviewboardCorePlugin
Index: ereviewboard/org.review_board.ereviewboard.core/OSGI-INF/l10n/bundle.properties
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/OSGI-INF/l10n/bundle.properties	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/OSGI-INF/l10n/bundle.properties	(revision 0)
@@ -0,0 +1,3 @@
+#Properties file for org.review_board.ereviewboard.core
+Bundle-Name = eReviewboard Core Plug-in
+Bundle-Vendor = Markus Knittig
\ No newline at end of file
Index: ereviewboard/org.review_board.ereviewboard.core/build.properties
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/build.properties	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/build.properties	(revision 0)
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               OSGI-INF/l10n/bundle.properties,\
+               lib/json-20080701.jar,\
+               lib/cloning-1.4.jar,\
+               lib/objenesis-1.1.jar
Index: ereviewboard/org.review_board.ereviewboard.core/lib/cloning-1.4.jar
===================================================================

Property changes on: ereviewboard/org.review_board.ereviewboard.core/lib/cloning-1.4.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: ereviewboard/org.review_board.ereviewboard.core/lib/json-20080701.jar
===================================================================

Property changes on: ereviewboard/org.review_board.ereviewboard.core/lib/json-20080701.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: ereviewboard/org.review_board.ereviewboard.core/lib/objenesis-1.1.jar
===================================================================

Property changes on: ereviewboard/org.review_board.ereviewboard.core/lib/objenesis-1.1.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardClientManager.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardClientManager.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardClientManager.java	(revision 0)
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.commons.net.AbstractWebLocation;
+import org.eclipse.mylyn.tasks.core.IRepositoryListener;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.TaskRepositoryLocationFactory;
+import org.review_board.ereviewboard.core.client.RestfulReviewboardClient;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.client.ReviewboardClientData;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardClientManager implements IRepositoryListener {
+
+    private Map<String, ReviewboardClient> clientByUrl = new HashMap<String, ReviewboardClient>();
+
+    private Map<String, ReviewboardClientData> dataByUrl = new HashMap<String, ReviewboardClientData>();
+
+    private TaskRepositoryLocationFactory taskRepositoryLocationFactory;
+
+    private File cacheFile;
+
+    public ReviewboardClientManager(File cacheFile) {
+        this.cacheFile = cacheFile;
+        readCache();
+    }
+
+    public synchronized ReviewboardClient getClient(TaskRepository taskRepository) {
+        String repositoryUrl = taskRepository.getRepositoryUrl();
+        ReviewboardClient repository = clientByUrl.get(repositoryUrl);
+
+        if (repository == null) {
+            AbstractWebLocation location = taskRepositoryLocationFactory
+                    .createWebLocation(taskRepository);
+
+            ReviewboardClientData data = dataByUrl.get(repositoryUrl);
+            if (data == null) {
+                data = new ReviewboardClientData();
+                dataByUrl.put(repositoryUrl, data);
+            }
+
+            repository = new RestfulReviewboardClient(location, data, taskRepository);
+            clientByUrl.put(taskRepository.getRepositoryUrl(), repository);
+        }
+
+        return repository;
+    }
+
+    public TaskRepositoryLocationFactory getTaskRepositoryLocationFactory() {
+        return taskRepositoryLocationFactory;
+    }
+
+    public void setTaskRepositoryLocationFactory(
+            TaskRepositoryLocationFactory taskRepositoryLocationFactory) {
+        this.taskRepositoryLocationFactory = taskRepositoryLocationFactory;
+    }
+
+    public void repositoryAdded(TaskRepository repository) {
+        repositorySettingsChanged(repository);
+    }
+
+    public void repositoryRemoved(TaskRepository repository) {
+        clientByUrl.remove(repository.getRepositoryUrl());
+        dataByUrl.remove(repository.getRepositoryUrl());
+    }
+
+    public void repositorySettingsChanged(TaskRepository repository) {
+        ReviewboardClient client = clientByUrl.get(repository.getRepositoryUrl());
+
+        if (client != null) {
+            client.refreshRepositorySettings(repository);
+        }
+    }
+
+    public void repositoryUrlChanged(TaskRepository repository, String oldUrl) {
+        clientByUrl.put(repository.getRepositoryUrl(), clientByUrl.remove(oldUrl));
+        dataByUrl.put(repository.getRepositoryUrl(), dataByUrl.remove(oldUrl));
+    }
+
+    private void readCache() {
+        if (cacheFile == null || !cacheFile.exists()) {
+            return;
+        }
+
+        ObjectInputStream in = null;
+        try {
+            in = new ObjectInputStream(new FileInputStream(cacheFile));
+
+            for (int count = in.readInt(); count > 0; count--) {
+                dataByUrl.put(in.readObject().toString(), (ReviewboardClientData) in.readObject());
+            }
+        } catch (Throwable e) {
+            StatusHandler.log(new Status(IStatus.WARNING, ReviewboardCorePlugin.PLUGIN_ID,
+                    "The Reviewboard respository data cache could not be read", e));
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e1) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    void writeCache() {
+        if (cacheFile == null) {
+            return;
+        }
+
+        ObjectOutputStream out = null;
+        try {
+            out = new ObjectOutputStream(new FileOutputStream(cacheFile));
+
+            out.writeInt(dataByUrl.size());
+            for (Entry<String, ReviewboardClientData> entry : dataByUrl.entrySet()) {
+                out.writeObject(entry.getKey());
+                out.writeObject(entry.getValue());
+            }
+
+            out.flush();
+        } catch (Throwable e) {
+            StatusHandler.log(new Status(IStatus.WARNING, ReviewboardCorePlugin.PLUGIN_ID,
+                    "The Reviewboard respository data cache could not be written", e));
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e1) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardClientManager.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardConstants.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardConstants.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardConstants.java	(revision 0)
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public final class ReviewboardConstants {
+
+    private ReviewboardConstants() {
+        super();
+    }
+
+    public static final String REVIEW_REQUEST_URL = "/r/";
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardConstants.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardCorePlugin.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardCorePlugin.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardCorePlugin.java	(revision 0)
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardCorePlugin extends Plugin {
+
+	public static final String PLUGIN_ID = "org.review_board.ereviewboard.core";
+
+	public static final String REPOSITORY_KIND = "reviewboard";
+
+	private static ReviewboardCorePlugin plugin;
+
+	private ReviewboardRepositoryConnector connector;
+
+	public static ReviewboardCorePlugin getDefault() {
+		return plugin;
+	}
+
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		if (connector != null) {
+			connector.stop();
+			connector = null;
+		}
+
+		plugin = null;
+		super.stop(context);
+	}
+
+	public ReviewboardRepositoryConnector getConnector() {
+		if (connector == null) {
+			setConnector(new ReviewboardRepositoryConnector());
+		}
+
+		return connector;
+	}
+
+	void setConnector(ReviewboardRepositoryConnector connector) {
+		this.connector = connector;
+	}
+
+	public IPath getRepostioryAttributeCachePath() {
+		IPath stateLocation = Platform.getStateLocation(getBundle());
+		IPath cacheFile = stateLocation.append("repositoryClientDataCache");
+        return cacheFile;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardCorePlugin.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardRepositoryConnector.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardRepositoryConnector.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardRepositoryConnector.java	(revision 0)
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core;
+
+import java.util.Date;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITaskMapping;
+import org.eclipse.mylyn.tasks.core.RepositoryResponse;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.TaskRepositoryLocationFactory;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
+import org.eclipse.mylyn.tasks.core.data.TaskMapper;
+import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardRepositoryConnector extends AbstractRepositoryConnector {
+
+    private static final String CLIENT_LABEL = "Reviewboard (supports 1.0 and later)";
+
+    private final static Pattern REVIEW_REQUEST_ID_FROM_TASK_URL = Pattern
+            .compile(ReviewboardConstants.REVIEW_REQUEST_URL + "(\\d+)");
+
+    private ReviewboardClientManager clientManager;
+
+    private TaskRepositoryLocationFactory taskRepositoryLocationFactory;
+
+    public ReviewboardRepositoryConnector() {
+        super();
+
+        if (ReviewboardCorePlugin.getDefault() != null) {
+            ReviewboardCorePlugin.getDefault().setConnector(this);
+        }
+    }
+
+    @Override
+    public boolean canCreateNewTask(TaskRepository repository) {
+        return repository.getConnectorKind().equals(getConnectorKind());
+    }
+
+    @Override
+    public boolean canCreateTaskFromKey(TaskRepository repository) {
+        return true;
+    }
+
+    @Override
+    public String getConnectorKind() {
+        return ReviewboardCorePlugin.REPOSITORY_KIND;
+    }
+
+    @Override
+    public String getLabel() {
+        return CLIENT_LABEL;
+    }
+
+    @Override
+    public String getRepositoryUrlFromTaskUrl(String taskFullUrl) {
+        int index = taskFullUrl.indexOf(ReviewboardConstants.REVIEW_REQUEST_URL);
+
+        if (index > 0) {
+            return taskFullUrl.substring(0, index);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public TaskData getTaskData(TaskRepository taskRepository, String taskId,
+            IProgressMonitor monitor) throws CoreException {
+        ReviewboardClient client = getClientManager().getClient(taskRepository);
+        return client.getTaskData(taskRepository, taskId, monitor);
+    }
+
+    @Override
+    public String getTaskIdFromTaskUrl(String taskFullUrl) {
+        Matcher matcher = REVIEW_REQUEST_ID_FROM_TASK_URL.matcher(taskFullUrl);
+
+        if (matcher.find()) {
+            return matcher.group(1);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public String getTaskUrl(String repositoryUrl, String taskId) {
+        return ReviewboardUtil.getReviewRequestUrl(repositoryUrl, taskId);
+    }
+
+    @Override
+    public boolean hasTaskChanged(TaskRepository taskRepository, ITask task, TaskData taskData) {
+        TaskMapper scheme = new TaskMapper(taskData);
+        Date repositoryDate = scheme.getModificationDate();
+        Date localeDate = task.getModificationDate();
+
+        if (localeDate != null) {
+            return !localeDate.equals(repositoryDate);
+        }
+
+        return true;
+    }
+
+    @Override
+    public IStatus performQuery(TaskRepository repository, IRepositoryQuery query,
+            TaskDataCollector collector, ISynchronizationSession session, IProgressMonitor monitor) {
+        ReviewboardClient client = getClientManager().getClient(repository);
+
+        try {
+            client.updateRepositoryData(false, monitor);
+            client.performQuery(repository, query, collector, monitor);
+        } catch (CoreException e) {
+            return e.getStatus();
+        }
+
+        return Status.OK_STATUS;
+    }
+
+    @Override
+    public void updateRepositoryConfiguration(TaskRepository taskRepository,
+            IProgressMonitor monitor) throws CoreException {
+        // ignore
+    }
+
+    @Override
+    public void updateTaskFromTaskData(TaskRepository taskRepository, ITask task, TaskData taskData) {
+        TaskMapper scheme = new TaskMapper(taskData);
+        scheme.applyTo(task);
+        task.setCompletionDate(scheme.getCompletionDate());
+    }
+
+    @Override
+    public boolean canSynchronizeTask(TaskRepository taskRepository, ITask task) {
+        return false;
+    }
+
+    public synchronized ReviewboardClientManager getClientManager() {
+        if (clientManager == null) {
+            IPath path = ReviewboardCorePlugin.getDefault().getRepostioryAttributeCachePath();
+            clientManager = new ReviewboardClientManager(path.toFile());
+        }
+        clientManager.setTaskRepositoryLocationFactory(taskRepositoryLocationFactory);
+
+        return clientManager;
+    }
+
+    public void stop() {
+        if (clientManager != null) {
+            clientManager.writeCache();
+        }
+    }
+
+    public void setTaskRepositoryLocationFactory(TaskRepositoryLocationFactory factory) {
+        this.taskRepositoryLocationFactory = factory;
+        if (clientManager != null) {
+            clientManager.setTaskRepositoryLocationFactory(factory);
+        }
+    }
+
+    @Override
+    public AbstractTaskDataHandler getTaskDataHandler() {
+        return new AbstractTaskDataHandler() {
+            @Override
+            public TaskAttributeMapper getAttributeMapper(TaskRepository taskRepository) {
+                return new TaskAttributeMapper(taskRepository) {
+                };
+            }
+
+            @Override
+            public boolean initializeTaskData(TaskRepository repository, TaskData data,
+                    ITaskMapping initializationData, IProgressMonitor monitor) throws CoreException {
+                // ignore
+                return false;
+            }
+
+              @Override
+            public RepositoryResponse postTaskData(TaskRepository repository, TaskData taskData,
+                    Set<TaskAttribute> oldAttributes, IProgressMonitor monitor)
+                    throws CoreException {
+                // ignore
+                return null;
+            }
+        };
+
+    }
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardRepositoryConnector.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardTaskMapper.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardTaskMapper.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardTaskMapper.java	(revision 0)
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core;
+
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskMapper;
+
+/**
+ * Utility class for mapping between TaskData and Task
+ *
+ * @author Markus Knittig
+ */
+public class ReviewboardTaskMapper extends TaskMapper {
+
+	public ReviewboardTaskMapper(TaskData taskData) {
+		super(taskData);
+	}
+
+	public ReviewboardTaskMapper(TaskData taskData,
+			boolean createNonExistingAttributes) {
+		super(taskData, createNonExistingAttributes);
+	}
+
+	public void setTaskKey(String key) {
+        setValue(TaskAttribute.TASK_KEY, key);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/ReviewboardTaskMapper.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardClient.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardClient.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardClient.java	(revision 0)
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.client;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.net.AbstractWebLocation;
+import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
+import org.eclipse.mylyn.commons.net.AuthenticationType;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+import org.review_board.ereviewboard.core.ReviewboardTaskMapper;
+import org.review_board.ereviewboard.core.exception.ReviewboardException;
+import org.review_board.ereviewboard.core.model.Comment;
+import org.review_board.ereviewboard.core.model.Repository;
+import org.review_board.ereviewboard.core.model.Review;
+import org.review_board.ereviewboard.core.model.ReviewGroup;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+import org.review_board.ereviewboard.core.model.User;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class RestfulReviewboardClient implements ReviewboardClient {
+
+    private final HttpClient httpClient;
+
+    private final RestfulReviewboardReader reviewboardReader;
+
+    private AbstractWebLocation location;
+
+    private ReviewboardClientData clientData;
+
+    private String cookie = "";
+
+    private String characterEncoding;
+
+    public RestfulReviewboardClient(AbstractWebLocation location, ReviewboardClientData clientData,
+            TaskRepository repository) {
+        this.location = location;
+        this.clientData = clientData;
+        this.httpClient = new HttpClient();
+        this.reviewboardReader = new RestfulReviewboardReader();
+        this.characterEncoding = repository.getCharacterEncoding();
+
+        this.httpClient.getParams().setContentCharset(characterEncoding);
+
+        refreshRepositorySettings(repository);
+    }
+
+    public ReviewboardClientData getClientData() {
+        return clientData;
+    }
+
+    public void refreshRepositorySettings(TaskRepository repository) {
+        // Nothing to do yet
+    }
+
+    public TaskData getTaskData(TaskRepository taskRepository, final String taskId,
+            IProgressMonitor monitor) {
+        // TODO Get review request
+
+        TaskData taskData = new TaskData(new TaskAttributeMapper(taskRepository),
+                ReviewboardCorePlugin.REPOSITORY_KIND, location.getUrl(), taskId);
+
+        return taskData;
+    }
+
+    public void login() /* throws ReviewboardException */{
+        PostMethod loginRequest = new PostMethod(location.getUrl() + "/api/json/accounts/login/");
+
+        AuthenticationCredentials credentials = location
+                .getCredentials(AuthenticationType.REPOSITORY);
+        loginRequest.setParameter("username", credentials.getUserName());
+        loginRequest.setParameter("password", credentials.getPassword());
+
+        try {
+            httpClient.executeMethod(loginRequest);
+            cookie = loginRequest.getResponseHeader("Set-Cookie").getValue();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String getCookie() {
+        if (cookie == "") {
+            login();
+        }
+
+        return cookie;
+    }
+
+    private GetMethod createGetMethod(String url) {
+        GetMethod getMethod = new GetMethod(stripSlash(location.getUrl()) + url);
+        getMethod.getParams().setParameter("Set-Cookie", getCookie());
+        return getMethod;
+    }
+
+    private PostMethod createPostMethod(String url) {
+        PostMethod postMethod = new PostMethod(stripSlash(location.getUrl()) + url);
+        postMethod.getParams().setParameter("Set-Cookie", getCookie());
+        return postMethod;
+    }
+
+    private String stripSlash(String url) {
+        if (url.endsWith("/")) {
+            return url.substring(0, url.lastIndexOf("/"));
+        }
+        return url;
+    }
+
+    private String executeGet(String url) {
+        GetMethod get = createGetMethod(url);
+
+        try {
+            httpClient.executeMethod(get);
+            return get.getResponseBodyAsString();
+        } catch (IOException e) {
+            new RuntimeException(e);
+        }
+
+        return "";
+    }
+
+    private String executePost(String url, JSONObject body) {
+        return executePost(url, body, new HashMap<String, String>());
+    }
+
+    private String executePost(String url) {
+        return executePost(url, new HashMap<String, String>());
+    }
+
+    private String executePost(String url, Map<String, String> parameters) {
+        PostMethod post = createPostMethod(url);
+
+        for (String key : parameters.keySet()) {
+            post.setParameter(key, parameters.get(key));
+        }
+
+        try {
+            httpClient.executeMethod(post);
+            return post.getResponseBodyAsString();
+        } catch (IOException e) {
+            new RuntimeException(e);
+        }
+
+        return "";
+    }
+
+    private String executePost(String url, JSONObject body, Map<String, String> parameters) {
+        PostMethod post = createPostMethod(url);
+
+        for (String key : parameters.keySet()) {
+            post.setParameter(key, parameters.get(key));
+        }
+
+        try {
+            post.setRequestEntity(new StringRequestEntity(body.toString(), "application/json",
+                    characterEncoding));
+            httpClient.executeMethod(post);
+            return post.getResponseBodyAsString();
+        } catch (IOException e) {
+            new RuntimeException(e);
+        }
+
+        return "";
+    }
+
+    public List<Repository> getRepositories() throws ReviewboardException {
+        return reviewboardReader.readRepositories(executeGet("/api/json/repositories/"));
+    }
+
+    public List<User> getUsers() throws ReviewboardException {
+        return reviewboardReader.readUsers(executeGet("/api/json/users/"));
+    }
+
+    public List<ReviewGroup> getReviewGroups() throws ReviewboardException {
+        return reviewboardReader.readGroups(executeGet("/api/json/groups/"));
+    }
+
+    public List<ReviewRequest> getReviewRequests(String query) throws ReviewboardException {
+        return reviewboardReader
+                .readReviewRequests(executeGet("/api/json/reviewrequests/" + query));
+    }
+
+    public ReviewRequest newReviewRequest(ReviewRequest reviewRequest) throws ReviewboardException {
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("repository_id", String.valueOf(reviewRequest.getRepository().getId()));
+        if (reviewRequest.getChangeNumber() != null) {
+            parameters.put("changenum", String.valueOf(reviewRequest.getChangeNumber()));
+        }
+
+        ReviewRequest newReviewRequest = reviewboardReader.readReviewRequest(executePost(
+                "/api/json/reviewrequests/new/", parameters));
+        reviewRequest.setId(newReviewRequest.getId());
+        reviewRequest.setTimeAdded(newReviewRequest.getTimeAdded());
+        reviewRequest.setLastUpdated(newReviewRequest.getLastUpdated());
+        reviewRequest.setSubmitter(newReviewRequest.getSubmitter());
+
+        //TODO
+        //reviewRequest.getTargetPeople().add(newReviewRequest.getSubmitter());
+        //reviewRequest.setSummary("Test");
+        //reviewRequest.setDescription("Test");
+        //updateReviewRequest(reviewRequest);
+
+        return reviewRequest;
+    }
+
+    public ReviewRequest getReviewRequest(int reviewRequestId) throws ReviewboardException {
+        return reviewboardReader.readReviewRequest(executeGet("/api/json/reviewrequests/"
+                + reviewRequestId + "/"));
+    }
+
+    public List<Review> getReviews(int reviewRequestId) throws ReviewboardException {
+        List<Review> result =  reviewboardReader.readReviews(executeGet("/api/json/reviewrequests/"
+                + reviewRequestId + "/reviews/"));
+
+        for (Review review : result) {
+            // Sort comments by line
+            Collections.sort(review.getComments(), new Comparator<Comment>() {
+                public int compare(Comment comment1, Comment comment2) {
+                    return ((Integer) comment1.getFirstLine()).compareTo(comment2.getFirstLine());
+                }
+            });
+        }
+
+        return result;
+    }
+
+    public void updateReviewRequest(ReviewRequest reviewRequest) throws ReviewboardException {
+        Map<String, String> parameters = new HashMap<String, String>();
+
+        parameters.put("status", reviewRequest.getStatus().toString());
+        //parameters.put("public", reviewRequest.getPublicReviewRequest());
+        parameters.put("summary", reviewRequest.getSummary());
+        parameters.put("description", reviewRequest.getDescription());
+        parameters.put("testing_done", reviewRequest.getTestingDone());
+        parameters.put("branch", reviewRequest.getBranch());
+        parameters.put("bugs_closed", ReviewboardUtil.unmarshallBugsClosed(reviewRequest.getBugsClosed()));
+        parameters.put("target_groups", ReviewboardUtil.unmarshallTargetGroup(reviewRequest.getTargetGroups()));
+        parameters.put("target_people", ReviewboardUtil.unmarshallTargetPeople(reviewRequest.getTargetPeople()));
+
+        executePost("/api/json/reviewrequests/" + reviewRequest.getId() + "/draft/set/",
+                parameters);
+        executePost("/api/json/reviewrequests/" + reviewRequest.getId() + "/draft/save/");
+        executePost("/api/json/reviewrequests/" + reviewRequest.getId() + "/publish/");
+    }
+
+    public boolean hasRepositoryData() {
+        return (clientData.lastupdate != 0);
+    }
+
+    public void updateRepositoryData(boolean force, IProgressMonitor monitor) {
+        if (hasRepositoryData() && !force) {
+            return;
+        }
+
+        try {
+            monitor.subTask("Retrieving Reviewboard groups");
+            clientData.setGroups(getReviewGroups());
+            monitorWorked(monitor);
+
+            monitor.subTask("Retrieving Reviewboard users");
+            clientData.setUsers(getUsers());
+            monitorWorked(monitor);
+
+            monitor.subTask("Retrieving Reviewboard repositories");
+            clientData.setRepositories(getRepositories());
+            monitorWorked(monitor);
+
+            clientData.lastupdate = new Date().getTime();
+        } catch (Exception e) {
+            // TODO: handle exception
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void monitorWorked(IProgressMonitor monitor) {
+        monitor.worked(1);
+        if (monitor.isCanceled()) {
+            throw new OperationCanceledException();
+        }
+    }
+
+    public void performQuery(TaskRepository repository, IRepositoryQuery query,
+            TaskDataCollector collector, IProgressMonitor monitor) throws CoreException {
+        try {
+            List<ReviewRequest> reviewRequests = getReviewRequests(query.getUrl());
+            for (ReviewRequest reviewRequest : reviewRequests) {
+                TaskData taskData = getTaskDataForReviewRequest(repository, reviewRequest);
+                collector.accept(taskData);
+            }
+        } catch (ReviewboardException e) {
+            throw new CoreException(Status.CANCEL_STATUS);
+        }
+    }
+
+    private TaskData getTaskDataForReviewRequest(TaskRepository taskRepository,
+            ReviewRequest reviewRequest) {
+        String summary = reviewRequest.getSummary();
+        String id = String.valueOf(reviewRequest.getId());
+        String owner = reviewRequest.getSubmitter().getUsername();
+        Date creationDate = reviewRequest.getTimeAdded();
+        Date dateModified = reviewRequest.getLastUpdated();
+        String description = reviewRequest.getDescription();
+
+        TaskData taskData = new TaskData(new TaskAttributeMapper(taskRepository),
+                ReviewboardCorePlugin.REPOSITORY_KIND, location.getUrl(), id);
+        taskData.setPartial(true);
+
+        ReviewboardTaskMapper mapper = new ReviewboardTaskMapper(taskData, true);
+        mapper.setTaskKey(id);
+        mapper.setCreationDate(creationDate);
+        mapper.setModificationDate(dateModified);
+        mapper.setSummary(summary);
+        mapper.setOwner(owner);
+        mapper.setDescription(description);
+        mapper.setTaskUrl(ReviewboardUtil.getReviewRequestUrl(taskRepository.getUrl(), id));
+
+        return taskData;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardClient.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardReader.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardReader.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardReader.java	(revision 0)
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.client;
+
+import java.util.List;
+
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.exception.ReviewboardException;
+import org.review_board.ereviewboard.core.model.Comment;
+import org.review_board.ereviewboard.core.model.Repository;
+import org.review_board.ereviewboard.core.model.Review;
+import org.review_board.ereviewboard.core.model.ReviewGroup;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+import org.review_board.ereviewboard.core.model.User;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class RestfulReviewboardReader {
+
+    public List<User> readUsers(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonUsers = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(User.class, jsonUsers.getJSONArray("users"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<ReviewGroup> readGroups(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonGroups = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(ReviewGroup.class, jsonGroups
+                    .getJSONArray("groups"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<ReviewRequest> readReviewRequests(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonReviewRequests = new JSONObject(source);
+            List<ReviewRequest> reviewRequests = ReviewboardUtil.parseEntities(ReviewRequest.class,
+                    jsonReviewRequests.getJSONArray("review_requests"));
+            return reviewRequests;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<Repository> readRepositories(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonRepositories = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(Repository.class, jsonRepositories
+                    .getJSONArray("repositories"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public ReviewRequest readReviewRequest(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonReviewRequest = new JSONObject(source);
+            return ReviewboardUtil.parseEntity(ReviewRequest.class, jsonReviewRequest
+                    .getJSONObject("review_request"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<Review> readReviews(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonReviewRequest = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(Review.class, jsonReviewRequest
+                    .getJSONArray("reviews"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<Comment> readComments(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonReviewRequest = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(Comment.class, jsonReviewRequest
+                    .getJSONArray("comments"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+    public List<Review> readReplies(String source) throws ReviewboardException {
+        try {
+            JSONObject jsonReviewRequest = new JSONObject(source);
+            return ReviewboardUtil.parseEntities(Review.class, jsonReviewRequest
+                    .getJSONArray("replies"));
+        } catch (Exception e) {
+            throw new ReviewboardException(e.getMessage(), e);
+        }
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/RestfulReviewboardReader.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClient.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClient.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClient.java	(revision 0)
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.client;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
+import org.review_board.ereviewboard.core.exception.ReviewboardException;
+import org.review_board.ereviewboard.core.model.Review;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public interface ReviewboardClient {
+
+    ReviewboardClientData getClientData();
+
+    void refreshRepositorySettings(TaskRepository repository);
+
+    List<ReviewRequest> getReviewRequests(String query) throws ReviewboardException;
+
+    ReviewRequest newReviewRequest(ReviewRequest reviewRequest) throws ReviewboardException;
+
+    ReviewRequest getReviewRequest(int reviewRequestId) throws ReviewboardException;
+
+    List<Review> getReviews(int reviewRequestId) throws ReviewboardException;
+
+    void updateReviewRequest(ReviewRequest reviewRequest) throws ReviewboardException;
+
+    void updateRepositoryData(boolean force, IProgressMonitor monitor);
+
+    boolean hasRepositoryData();
+
+    TaskData getTaskData(TaskRepository taskRepository, String taskId, IProgressMonitor monitor);
+
+    void performQuery(TaskRepository repository, IRepositoryQuery query,
+            TaskDataCollector collector, IProgressMonitor monitor) throws CoreException;
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClient.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClientData.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClientData.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClientData.java	(revision 0)
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.client;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.review_board.ereviewboard.core.model.Repository;
+import org.review_board.ereviewboard.core.model.ReviewGroup;
+import org.review_board.ereviewboard.core.model.User;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardClientData implements Serializable {
+
+    private static final long serialVersionUID = 9156255577082704349L;
+
+    private List<User> users = new ArrayList<User>();
+    private List<ReviewGroup> groups = new ArrayList<ReviewGroup>();
+    private List<Repository> repositories = new ArrayList<Repository>();
+
+    long lastupdate = 0;
+
+    /**
+     * @return the users
+     */
+    public List<User> getUsers() {
+        return users;
+    }
+
+    /**
+     * @param users the users to set
+     */
+    public void setUsers(List<User> users) {
+        this.users = users;
+    }
+
+    /**
+     * @return the groups
+     */
+    public List<ReviewGroup> getGroups() {
+        return groups;
+    }
+
+    /**
+     * @param groups the groups to set
+     */
+    public void setGroups(List<ReviewGroup> groups) {
+        this.groups = groups;
+    }
+
+    /**
+     * @return the repositories
+     */
+    public List<Repository> getRepositories() {
+        return repositories;
+    }
+
+    /**
+     * @param repositories the repositories to set
+     */
+    public void setRepositories(List<Repository> repositories) {
+        this.repositories = repositories;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/client/ReviewboardClientData.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/exception/ReviewboardException.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/exception/ReviewboardException.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/exception/ReviewboardException.java	(revision 0)
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.exception;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardException extends Exception {
+
+    private static final long serialVersionUID = -7600603951139662547L;
+
+    public ReviewboardException() {
+        super();
+    }
+
+    public ReviewboardException(String message, Exception exception) {
+        super(message, exception);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/exception/ReviewboardException.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/AllReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/AllReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/AllReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class AllReviewRequestQuery extends StatusReviewRequestQuery {
+
+    private static final long serialVersionUID = 7439335361296671368L;
+
+    public AllReviewRequestQuery(ReviewRequestStatus status) {
+        super(status);
+    }
+
+    @Override
+    public String getQuery() {
+        return "all" + super.getQuery();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/AllReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Comment.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Comment.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Comment.java	(revision 0)
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.util.Date;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class Comment implements Marshallable {
+
+    private static final long serialVersionUID = 2864269615892045077L;
+
+    private int id;
+    private Comment replyTo;
+    private Date timestamp;
+    private String text;
+    private User user;
+    private int firstLine;
+    private int numLines;
+    private FileDiff fileDiff;
+    private FileDiff interFileDiff;
+    private boolean publicComment;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public Comment getReplyTo() {
+        return replyTo;
+    }
+
+    public void setReplyTo(Comment replyTo) {
+        this.replyTo = replyTo;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public int getFirstLine() {
+        return firstLine;
+    }
+
+    public void setFirstLine(int firstLine) {
+        this.firstLine = firstLine;
+    }
+
+    public int getNumLines() {
+        return numLines;
+    }
+
+    public void setNumLines(int numLines) {
+        this.numLines = numLines;
+    }
+
+    public int getLastLine() {
+        return firstLine + numLines;
+    }
+
+    public FileDiff getFileDiff() {
+        return fileDiff;
+    }
+
+    public void setFileDiff(FileDiff fileDiff) {
+        this.fileDiff = fileDiff;
+    }
+
+    public FileDiff getInterFileDiff() {
+        return interFileDiff;
+    }
+
+    public void setInterFileDiff(FileDiff interFileDiff) {
+        this.interFileDiff = interFileDiff;
+    }
+
+    public boolean isPublicComment() {
+        return publicComment;
+    }
+
+    public void setPublicComment(boolean publicComment) {
+        this.publicComment = publicComment;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            if (jsonObject.has("reply_to")) {
+                replyTo = ReviewboardUtil.parseEntity(Comment.class, jsonObject
+                        .getJSONObject("reply_to"));
+            } else {
+                replyTo = null;
+            }
+            timestamp = ReviewboardUtil.marshallDate(jsonObject.getString("timestamp"));
+            text = jsonObject.getString("text");
+            user = ReviewboardUtil.parseEntity(User.class, jsonObject
+                    .getJSONObject("user"));
+            fileDiff = ReviewboardUtil.parseEntity(FileDiff.class, jsonObject
+                    .getJSONObject("filediff"));
+            if (jsonObject.getString("interfilediff").equals("null")) {
+                interFileDiff = null;
+            } else {
+                interFileDiff = ReviewboardUtil.parseEntity(FileDiff.class, jsonObject
+                        .getJSONObject("interfilediff"));
+            }
+            firstLine = jsonObject.getInt("first_line");
+            numLines = jsonObject.getInt("num_lines");
+            publicComment = ReviewboardUtil.marshallBoolean(jsonObject, "public");
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            if (replyTo != null) {
+                jsonObject.put("reply_to", replyTo.unmarshall());
+            }
+            jsonObject.put("timestamp", ReviewboardUtil.unmarshallDate(timestamp));
+            jsonObject.put("text", text);
+            jsonObject.put("user", user.unmarshall());
+            jsonObject.put("filediff", fileDiff.unmarshall());
+            if (interFileDiff == null) {
+                jsonObject.put("interfilediff", "null");
+            } else {
+                jsonObject.put("interfilediff", interFileDiff);
+            }
+            jsonObject.put("first_line", firstLine);
+            jsonObject.put("num_lines", numLines);
+            jsonObject.put("public", ReviewboardUtil.unmarshallBoolean(publicComment));
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Comment.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/DiffSet.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/DiffSet.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/DiffSet.java	(revision 0)
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.util.Date;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class DiffSet implements Marshallable {
+
+    private static final long serialVersionUID = 7279481793108470862L;
+
+    private int id;
+    private String name;
+    private Date timestamp;
+    private int revision;
+    private Repository repository;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public int getRevision() {
+        return revision;
+    }
+
+    public void setRevision(int revision) {
+        this.revision = revision;
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+    public void setRepository(Repository repository) {
+        this.repository = repository;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            name = jsonObject.getString("name");
+            timestamp = ReviewboardUtil.marshallDate(jsonObject.getString("timestamp"));
+            revision = jsonObject.getInt("revision");
+            repository = ReviewboardUtil.parseEntity(Repository.class, jsonObject
+                    .getJSONObject("repository"));
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("name", name);
+            jsonObject.put("timestamp", ReviewboardUtil.unmarshallDate(timestamp));;
+            jsonObject.put("revision", revision);
+            jsonObject.put("repository", repository.unmarshall());
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/DiffSet.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FileDiff.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FileDiff.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FileDiff.java	(revision 0)
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class FileDiff implements Marshallable {
+
+    private static final long serialVersionUID = -5573524996122740041L;
+
+    private int id;
+    private DiffSet diffSet;
+    private String destDetail;
+    private String sourceRevision;
+    private String sourceFile;
+    private String destFile;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public DiffSet getDiffSet() {
+        return diffSet;
+    }
+
+    public void setDiffSet(DiffSet diffSet) {
+        this.diffSet = diffSet;
+    }
+
+    public String getDestDetail() {
+        return destDetail;
+    }
+
+    public void setDestDetail(String destDetail) {
+        this.destDetail = destDetail;
+    }
+
+    public String getSourceRevision() {
+        return sourceRevision;
+    }
+
+    public void setSourceRevision(String sourceRevision) {
+        this.sourceRevision = sourceRevision;
+    }
+
+    public String getSourceFile() {
+        return sourceFile;
+    }
+
+    public void setSourceFile(String sourceFile) {
+        this.sourceFile = sourceFile;
+    }
+
+    public String getDestFile() {
+        return destFile;
+    }
+
+    public void setDestFile(String destFile) {
+        this.destFile = destFile;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            diffSet = ReviewboardUtil.parseEntity(DiffSet.class, jsonObject
+                    .getJSONObject("diffset"));
+            destDetail = jsonObject.getString("dest_detail");
+            sourceRevision = jsonObject.getString("source_revision");
+            sourceFile = jsonObject.getString("source_file");
+            destFile = jsonObject.getString("dest_file");
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("diffset", diffSet.unmarshall());
+            jsonObject.put("dest_detail", destDetail);
+            jsonObject.put("source_revision", sourceRevision);
+            jsonObject.put("source_file", sourceFile);
+            jsonObject.put("dest_file", destFile);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FileDiff.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FromUserReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FromUserReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FromUserReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class FromUserReviewRequestQuery extends StatusReviewRequestQuery {
+
+    private static final long serialVersionUID = -5201497564898606678L;
+
+    private String username;
+
+    public FromUserReviewRequestQuery(ReviewRequestStatus status, String username) {
+        super(status);
+        this.username = username;
+    }
+
+    @Override
+    public String getQuery() {
+        return "from/user/" + username + super.getQuery();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/FromUserReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/GroupReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/GroupReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/GroupReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class GroupReviewRequestQuery extends StatusReviewRequestQuery {
+
+    private static final long serialVersionUID = -6024320417154430028L;
+
+    private String groupname;
+
+    public GroupReviewRequestQuery(ReviewRequestStatus status, String groupname) {
+        super(status);
+        this.groupname = groupname;
+    }
+
+    @Override
+    public String getQuery() {
+        return "to/group/" + groupname + super.getQuery();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/GroupReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Marshallable.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Marshallable.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Marshallable.java	(revision 0)
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.io.Serializable;
+
+import org.json.JSONObject;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public interface Marshallable extends Serializable {
+
+    void marshall(JSONObject jsonObject);
+
+    JSONObject unmarshall();
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Marshallable.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Repository.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Repository.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Repository.java	(revision 0)
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class Repository implements Marshallable {
+
+    private static final long serialVersionUID = 67636667992419648L;
+
+    private int id;
+    private String name;
+    private String tool;
+    private String path;
+
+    /**
+     * @return the id
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * @param id the id to set
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the tool
+     */
+    public String getTool() {
+        return tool;
+    }
+
+    /**
+     * @param tool the tool to set
+     */
+    public void setTool(String tool) {
+        this.tool = tool;
+    }
+
+    /**
+     * @return the path
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * @param path the path to set
+     */
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            name = jsonObject.getString("name");
+            tool = jsonObject.getString("tool");
+            path = jsonObject.getString("path");
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("name", name);
+            jsonObject.put("tool", tool);
+            jsonObject.put("path", path);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Repository.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/RepositoryReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/RepositoryReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/RepositoryReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class RepositoryReviewRequestQuery extends StatusReviewRequestQuery {
+
+    private static final long serialVersionUID = 8251782614497103435L;
+
+    private int repositoryId;
+    private int changeNum;
+
+    public RepositoryReviewRequestQuery(ReviewRequestStatus status, int repositoryId, int changeNum) {
+        super(status);
+        this.repositoryId = repositoryId;
+        this.changeNum = changeNum;
+    }
+
+    @Override
+    public String getQuery() {
+        return "repository/" + repositoryId + "/changenum/" + changeNum + super.getQuery();
+    }
+
+    public boolean isValid() {
+        return (changeNum > 0);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/RepositoryReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Review.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Review.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Review.java	(revision 0)
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.util.Date;
+import java.util.List;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class Review implements Marshallable {
+
+    private static final long serialVersionUID = -7242357272778386934L;
+
+    private int id;
+    private String bodyTop;
+    private String bodyBottom;
+    private int shipIt;
+    private Date timestamp;
+    private User user;
+    private boolean publicReview;
+    private List<Comment> comments;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getBodyTop() {
+        return bodyTop;
+    }
+
+    public void setBodyTop(String bodyTop) {
+        this.bodyTop = bodyTop;
+    }
+
+    public String getBodyBottom() {
+        return bodyBottom;
+    }
+
+    public void setBodyBottom(String bodyBottom) {
+        this.bodyBottom = bodyBottom;
+    }
+
+    public int getShipIt() {
+        return shipIt;
+    }
+
+    public void setShipIt(int shipIt) {
+        this.shipIt = shipIt;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public boolean isPublicReview() {
+        return publicReview;
+    }
+
+    public void setPublicReview(boolean publicReview) {
+        this.publicReview = publicReview;
+    }
+
+    public List<Comment> getComments() {
+        return comments;
+    }
+
+    public void setComments(List<Comment> comments) {
+        this.comments = comments;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            bodyTop = jsonObject.getString("body_top");
+            bodyBottom = jsonObject.getString("body_bottom");
+            shipIt = jsonObject.getInt("ship_it");
+            timestamp = ReviewboardUtil.marshallDate(jsonObject.getString("timestamp"));
+            user = ReviewboardUtil.parseEntity(User.class, jsonObject
+                    .getJSONObject("user"));
+            publicReview = ReviewboardUtil.marshallBoolean(jsonObject, "public");
+            comments = ReviewboardUtil.parseEntities(Comment.class, jsonObject
+                    .getJSONArray("comments"));
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("body_top", bodyTop);
+            jsonObject.put("body_bottom", bodyBottom);
+            jsonObject.put("ship_it", shipIt);
+            jsonObject.put("timestamp", ReviewboardUtil.unmarshallDate(timestamp));;
+            jsonObject.put("user", user.unmarshall());
+            jsonObject.put("public", ReviewboardUtil.unmarshallBoolean(publicReview));
+            //FIXME unmarshall
+            jsonObject.put("comments", comments);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/Review.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewGroup.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewGroup.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewGroup.java	(revision 0)
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewGroup implements Marshallable {
+
+    private static final long serialVersionUID = -7358663117616402113L;
+
+    private int id;
+    private String name;
+    private String displayName;
+    private String url;
+    private String mailingList;
+
+    public ReviewGroup() {
+        super();
+    }
+
+    public ReviewGroup(String name) {
+        super();
+        this.name = name;
+    }
+
+    /**
+     * @return the id
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * @param id the id to set
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the displayName
+     */
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    /**
+     * @param displayName the displayName to set
+     */
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    /**
+     * @return the url
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * @param url the url to set
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * @return the mailingList
+     */
+    public String getMailingList() {
+        return mailingList;
+    }
+
+    /**
+     * @param mailingList the mailingList to set
+     */
+    public void setMailingList(String mailingList) {
+        this.mailingList = mailingList;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            name = jsonObject.getString("name");
+            displayName = jsonObject.getString("display_name");
+            url = jsonObject.getString("url");
+            mailingList = jsonObject.getString("mailing_list");
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("name", name);
+            jsonObject.put("display_name", displayName);
+            jsonObject.put("url", url);
+            jsonObject.put("mailing_list", mailingList);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof ReviewGroup)) {
+            return false;
+        }
+        ReviewGroup other = (ReviewGroup) obj;
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        return true;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewGroup.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequest.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequest.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequest.java	(revision 0)
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewRequest implements Marshallable {
+
+    private static final long serialVersionUID = -1054552171768941863L;
+
+    private int id;
+    private User submitter;
+    private Date timeAdded;
+    private Date lastUpdated;
+    private ReviewRequestStatus status = ReviewRequestStatus.PENDING;
+    private boolean publicReviewRequest;
+    private Integer changeNumber;
+    private Repository repository;
+    private String summary = "";
+    private String description = "";
+    private String testingDone = "";
+    private List<Integer> bugsClosed = new ArrayList<Integer>();
+    private String branch = "";
+    private List<ReviewGroup> targetGroups = new ArrayList<ReviewGroup>();
+    private List<User> targetPeople = new ArrayList<User>();
+
+    // TODO Add Diffs
+    // TODO Add Screenshots
+    // TODO Add Inactive screenshots
+    // TODO Add Change descriptions
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public User getSubmitter() {
+        return submitter;
+    }
+
+    public void setSubmitter(User submitter) {
+        this.submitter = submitter;
+    }
+
+    public Date getTimeAdded() {
+        return timeAdded;
+    }
+
+    public void setTimeAdded(Date timeAdded) {
+        this.timeAdded = timeAdded;
+    }
+
+    public void setLastUpdated(Date lastUpdated) {
+        this.lastUpdated = lastUpdated;
+    }
+
+    public Date getLastUpdated() {
+        return lastUpdated;
+    }
+
+    public ReviewRequestStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(ReviewRequestStatus status) {
+        this.status = status;
+    }
+
+    public boolean isPublic() {
+        return publicReviewRequest;
+    }
+
+    public void setPublic(boolean isPublic) {
+        this.publicReviewRequest = isPublic;
+    }
+
+    public Integer getChangeNumber() {
+        return changeNumber;
+    }
+
+    public void setChangeNumber(Integer changeNumber) {
+        this.changeNumber = changeNumber;
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+    public void setRepository(Repository repository) {
+        this.repository = repository;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getTestingDone() {
+        return testingDone;
+    }
+
+    public void setTestingDone(String testingDone) {
+        this.testingDone = testingDone;
+    }
+
+    public List<Integer> getBugsClosed() {
+        return bugsClosed;
+    }
+
+    public void setBugsClosed(List<Integer> bugsClosed) {
+        this.bugsClosed = bugsClosed;
+    }
+
+    public String getBranch() {
+        return branch;
+    }
+
+    public void setBranch(String branch) {
+        this.branch = branch;
+    }
+
+    public List<ReviewGroup> getTargetGroups() {
+        return targetGroups;
+    }
+
+    public void setTargetGroups(List<ReviewGroup> targetGroups) {
+        this.targetGroups = targetGroups;
+    }
+
+    public List<User> getTargetPeople() {
+        return targetPeople;
+    }
+
+    public void setTargetPeople(List<User> targetUsers) {
+        this.targetPeople = targetUsers;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            submitter = ReviewboardUtil.parseEntity(User.class, jsonObject
+                    .getJSONObject("submitter"));
+            timeAdded = ReviewboardUtil.marshallDate(jsonObject.getString("time_added"));
+            lastUpdated = ReviewboardUtil.marshallDate(jsonObject.getString("last_updated"));
+            status = ReviewRequestStatus.parseStatus(jsonObject.getString("status"));
+            publicReviewRequest = ReviewboardUtil.marshallBoolean(jsonObject, "public");
+            marshallChangeNumber(jsonObject);
+            repository = ReviewboardUtil.parseEntity(Repository.class, jsonObject
+                    .getJSONObject("repository"));
+            summary = jsonObject.getString("summary");
+            description = jsonObject.getString("description");
+            testingDone = jsonObject.getString("testing_done");
+            marshallClosedBugs(jsonObject);
+            branch = jsonObject.getString("branch");
+            targetGroups = ReviewboardUtil.parseEntities(ReviewGroup.class, jsonObject
+                    .getJSONArray("target_groups"));
+            targetPeople = ReviewboardUtil.parseEntities(User.class, jsonObject
+                    .getJSONArray("target_people"));
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void marshallChangeNumber(JSONObject jsonObject) {
+        try {
+            changeNumber = jsonObject.getInt("changenum");
+        } catch (JSONException e) {
+            // ignore
+        }
+    }
+
+    private void marshallClosedBugs(JSONObject jsonObject) {
+        try {
+            JSONArray jsonBugsClosed = jsonObject.getJSONArray("bugs_closed");
+            bugsClosed.clear();
+            for (int iter = 0; iter < jsonBugsClosed.length(); iter++) {
+                // FIXME Should string like "1 2" be parsed or is this a Review
+                // Board bug?
+                String bugsClosedString = jsonBugsClosed.getString(iter);
+                bugsClosed.add(Integer.parseInt(bugsClosedString));
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("submitter", submitter.unmarshall());
+            jsonObject.put("time_added", ReviewboardUtil.unmarshallDate(timeAdded));
+            jsonObject.put("last_updated", ReviewboardUtil.unmarshallDate(lastUpdated));
+            jsonObject.put("text", status);
+            jsonObject.put("public", ReviewboardUtil.unmarshallBoolean(publicReviewRequest));
+            jsonObject.put("changenum", changeNumber);
+            jsonObject.put("repository", repository.unmarshall());
+            jsonObject.put("summary", summary);
+            jsonObject.put("description", description);
+            jsonObject.put("testing_done", testingDone);
+            jsonObject.put("bugs_closed", bugsClosed);
+            jsonObject.put("branch", branch);
+            jsonObject.put("target_groups", targetGroups);
+            jsonObject.put("target_people", targetPeople);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequest.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import java.io.Serializable;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public interface ReviewRequestQuery extends Serializable {
+
+    String getQuery();
+
+    void setStatus(ReviewRequestStatus status);
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestStatus.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestStatus.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestStatus.java	(revision 0)
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public enum ReviewRequestStatus {
+
+    PENDING,
+    SUBMITTED,
+    DISCARDED,
+    NONE;
+
+    public static ReviewRequestStatus parseStatus(String status) {
+    	ReviewRequestStatus result;
+
+    	switch (status.charAt(0)) {
+		case 'P':
+			result = ReviewRequestStatus.PENDING;
+			break;
+		case 'S':
+			result = ReviewRequestStatus.SUBMITTED;
+			break;
+		case 'D':
+			result = ReviewRequestStatus.DISCARDED;
+			break;
+		default:
+			result = ReviewRequestStatus.NONE;
+		}
+
+    	return result;
+    }
+
+    @Override
+    public String toString() {
+    	if (super.toString().startsWith("N")) {
+    		return "";
+    	} else {
+    		return super.toString().substring(0, 1);
+    	}
+    }
+
+    public String getDisplayname() {
+    	return super.toString().substring(0, 1) + super.toString().substring(1).toLowerCase();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ReviewRequestStatus.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/StatusReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/StatusReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/StatusReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public abstract class StatusReviewRequestQuery implements ReviewRequestQuery {
+
+    private static final long serialVersionUID = 548167898358271285L;
+
+    private ReviewRequestStatus status;
+
+    public StatusReviewRequestQuery(ReviewRequestStatus status) {
+        super();
+        this.status = status;
+    }
+
+    public String getQuery() {
+        if (status == null) {
+            return "";
+        } else {
+            return "/?status=" + status.getDisplayname().toLowerCase();
+        }
+    }
+
+    public void setStatus(ReviewRequestStatus status) {
+        this.status = status;
+    }
+
+    public static ReviewRequestQuery fromQueryString(String queryString) {
+        ReviewRequestQuery result = null;
+        ReviewRequestStatus status = ReviewRequestStatus.PENDING;
+
+        int statusIndex = queryString.indexOf("?");
+        if (statusIndex > 0) {
+            status = ReviewRequestStatus.parseStatus(queryString.substring(statusIndex + 8));
+        } else {
+            statusIndex = queryString.length();
+        }
+
+        if (queryString.startsWith("/to/group/")) {
+            result = new GroupReviewRequestQuery(status, queryString.substring(11, statusIndex));
+        } else if (queryString.startsWith("/to/user/")) {
+            result = new ToUserReviewRequestQuery(status, queryString.substring(9, statusIndex));
+        } else if (queryString.startsWith("/from/user/")) {
+            result = new FromUserReviewRequestQuery(status, queryString.substring(11, statusIndex));
+        } else if (queryString.startsWith("/repository/")) {
+            int changeNumIndex = queryString.indexOf("/changenum/");
+            result = new RepositoryReviewRequestQuery(status, Integer.parseInt(queryString
+                    .substring(12, changeNumIndex)), Integer.parseInt(queryString.substring(
+                    changeNumIndex + 11, statusIndex)));
+        } else {
+            result = new AllReviewRequestQuery(status);
+        }
+
+        return result;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/StatusReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ToUserReviewRequestQuery.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ToUserReviewRequestQuery.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ToUserReviewRequestQuery.java	(revision 0)
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ToUserReviewRequestQuery extends StatusReviewRequestQuery {
+
+    private static final long serialVersionUID = -4394473721628340148L;
+
+    private String username;
+
+    public ToUserReviewRequestQuery(ReviewRequestStatus status, String username) {
+        super(status);
+        this.username = username;
+    }
+
+    @Override
+    public String getQuery() {
+        return "to/user/" + username + super.getQuery();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/ToUserReviewRequestQuery.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/User.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/User.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/User.java	(revision 0)
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.model;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class User implements Marshallable {
+
+    private static final long serialVersionUID = -7560403653228576009L;
+
+    private int id;
+    private String username;
+    private String firstName;
+    private String lastName;
+    private String url;
+    private String email;
+
+    public User() {
+        super();
+    }
+
+    public User(JSONObject jsonObject) throws JSONException {
+        super();
+        marshall(jsonObject);
+    }
+
+    public User(String username) {
+        super();
+        this.username = username;
+    }
+
+    /**
+     * @return the id
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * @param id the id to set
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the username
+     */
+    public String getUsername() {
+        return username;
+    }
+
+    /**
+     * @param username the username to set
+     */
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    /**
+     * @return the firstName
+     */
+    public String getFirstName() {
+        return firstName;
+    }
+
+    /**
+     * @param firstName the firstName to set
+     */
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    /**
+     * @return the lastName
+     */
+    public String getLastName() {
+        return lastName;
+    }
+
+    /**
+     * @param lastName the lastName to set
+     */
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    /**
+     * @return the url
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * @param url the url to set
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * @return the email
+     */
+    public String getEmail() {
+        return email;
+    }
+
+    /**
+     * @param email the email to set
+     */
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    /**
+     * @return the fullName
+     */
+    public String getFullName() {
+        return firstName + " " + lastName;
+    }
+
+    public void marshall(JSONObject jsonObject) {
+        try {
+            id = jsonObject.getInt("id");
+            url = jsonObject.getString("url");
+            username = jsonObject.getString("username");
+            email = jsonObject.getString("email");
+            firstName = jsonObject.getString("first_name");
+            lastName = jsonObject.getString("last_name");
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public JSONObject unmarshall() {
+        JSONObject jsonObject = new JSONObject();
+
+        try {
+            jsonObject.put("id", id);
+            jsonObject.put("url", url);
+            jsonObject.put("username", username);
+            jsonObject.put("email", email);
+            jsonObject.put("first_name", firstName);
+            jsonObject.put("last_name", lastName);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+
+        return jsonObject;
+    }
+
+    @Override
+    public String toString() {
+        return username;
+    }
+
+    /**
+     * @generated
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((username == null) ? 0 : username.hashCode());
+        return result;
+    }
+
+    /**
+     * @generated
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        User other = (User) obj;
+        if (username == null) {
+            if (other.username != null)
+                return false;
+        } else if (!username.equals(other.username))
+            return false;
+        return true;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/model/User.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/util/ReviewboardUtil.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/util/ReviewboardUtil.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/util/ReviewboardUtil.java	(revision 0)
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.core.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.review_board.ereviewboard.core.ReviewboardConstants;
+import org.review_board.ereviewboard.core.client.ReviewboardClientData;
+import org.review_board.ereviewboard.core.model.Marshallable;
+import org.review_board.ereviewboard.core.model.ReviewGroup;
+import org.review_board.ereviewboard.core.model.User;
+
+import com.rits.cloning.Cloner;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public final class ReviewboardUtil {
+
+    private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    private static Cloner cloner = new Cloner();
+
+    private ReviewboardUtil() {
+        super();
+    }
+
+    public static Date marshallDate(String time) {
+        Date date = null;
+
+        try {
+            date = dateFormat.parse(time);
+        } catch (ParseException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+
+        return date;
+    }
+
+    public static String unmarshallDate(Date date) {
+        return dateFormat.format(date);
+    }
+
+    public static boolean marshallBoolean(JSONObject jsonObject, String key) {
+        try {
+            Object bool = jsonObject.get(key);
+            if (bool instanceof Boolean) {
+                return (Boolean) bool;
+            } else {
+                if (((Integer) bool) > 0) {
+                    return true;
+                }
+
+                return false;
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+        return false;
+    }
+
+    public static int unmarshallBoolean(boolean bool) {
+        if (bool) {
+            return 1;
+        }
+
+        return 0;
+    }
+
+    public static <T extends Marshallable> T parseEntity(Class<T> entityClass, JSONObject jsonObject) {
+        T entity = null;
+
+        try {
+            entity = entityClass.newInstance();
+            entity.marshall(jsonObject);
+        } catch (Exception e) {
+            entity = null;
+        }
+
+        return entity;
+    }
+
+    public static <T extends Marshallable> List<T> parseEntities(Class<T> entityClass,
+            JSONArray jsonArray) {
+        List<T> entities = new ArrayList<T>();
+
+        try {
+            for (int iter = 0; iter < jsonArray.length(); iter++) {
+                T entity = entityClass.newInstance();
+                entity.marshall(jsonArray.getJSONObject(iter));
+                entities.add(entity);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+
+        return entities;
+    }
+
+    public static String getReviewRequestUrl(String repositoryUrl, String taskId) {
+        return repositoryUrl + ReviewboardConstants.REVIEW_REQUEST_URL + taskId;
+    }
+
+    public static <T> T cloneEntity(T entity) {
+        return cloner.deepClone(entity);
+    }
+
+    public static String unmarshallBugsClosed(List<Integer> bugsClosed) {
+        StringBuilder result = new StringBuilder();
+
+        for (Integer bugClosed : bugsClosed) {
+            result.append(", ");
+            result.append(String.valueOf(bugClosed));
+        }
+
+        return substractComma(result.toString());
+    }
+
+    public static String unmarshallTargetPeople(List<User> targetPeople) {
+        StringBuilder result = new StringBuilder();
+
+        for (User user : targetPeople) {
+            result.append(", ");
+            result.append(user.getUsername());
+        }
+
+        return substractComma(result.toString());
+    }
+
+    public static String unmarshallTargetGroup(List<ReviewGroup> targetGroup) {
+        StringBuilder result = new StringBuilder();
+
+        for (ReviewGroup group : targetGroup) {
+            result.append(", ");
+            result.append(group.getName());
+        }
+
+        return substractComma(result.toString());
+    }
+
+    public static String substractComma(String string) {
+        if (string.length() > 2) {
+            return string.substring(2);
+        }
+        return "";
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.core/src/org/review_board/ereviewboard/core/util/ReviewboardUtil.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.tests.feature/.project
===================================================================
--- ereviewboard/org.review_board.ereviewboard.tests.feature/.project	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.tests.feature/.project	(revision 0)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.review_board.ereviewboard.tests.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
Index: ereviewboard/org.review_board.ereviewboard.tests.feature/build.properties
===================================================================
--- ereviewboard/org.review_board.ereviewboard.tests.feature/build.properties	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.tests.feature/build.properties	(revision 0)
@@ -0,0 +1 @@
+bin.includes = feature.xml
Index: ereviewboard/org.review_board.ereviewboard.tests.feature/feature.xml
===================================================================
--- ereviewboard/org.review_board.ereviewboard.tests.feature/feature.xml	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.tests.feature/feature.xml	(revision 0)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.review_board.ereviewboard.tests.feature"
+      label="eReviewboard Tests Feature"
+      version="0.1"
+      provider-name="Markus Knittig">
+
+   <description url="http://www.example.com/description">
+      [Enter Feature Description here.]
+   </description>
+
+   <copyright url="http://www.example.com/copyright">
+      [Enter Copyright Description here.]
+   </copyright>
+
+   <license url="http://www.example.com/license">
+      [Enter License Description here.]
+   </license>
+
+   <includes
+         id="org.review_board.ereviewboard"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.review_board.ereviewboard.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.junit"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+</feature>

Property changes on: ereviewboard/org.review_board.ereviewboard.tests.feature/feature.xml
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/.classpath
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/.classpath	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/.classpath	(revision 0)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: ereviewboard/org.review_board.ereviewboard.ui/.project
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/.project	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/.project	(revision 0)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.review_board.ereviewboard.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: ereviewboard/org.review_board.ereviewboard.ui/META-INF/MANIFEST.MF
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/META-INF/MANIFEST.MF	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/META-INF/MANIFEST.MF	(revision 0)
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.review_board.ereviewboard.ui;singleton:=true
+Bundle-Version: 0.1
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.mylyn.tasks.core;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.mylyn.tasks.ui;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.jface,
+ org.review_board.ereviewboard.core,
+ org.eclipse.ui,
+ org.eclipse.ui.forms,
+ org.eclipse.core.databinding,
+ org.eclipse.core.databinding.beans,
+ org.eclipse.core.databinding.observable,
+ org.eclipse.core.databinding.property,
+ org.eclipse.jface.databinding
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.review_board.ereviewboard.ui.ReviewboardUiPlugin
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.review_board.ereviewboard.ui,
+ org.review_board.ereviewboard.ui.wizard
Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardConnectorUi.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardConnectorUi.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardConnectorUi.java	(revision 0)
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui;
+
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITaskMapping;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage;
+import org.eclipse.mylyn.tasks.ui.wizards.RepositoryQueryWizard;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+import org.review_board.ereviewboard.core.ReviewboardRepositoryConnector;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.ui.wizard.NewReviewboardReviewRequestWizard;
+import org.review_board.ereviewboard.ui.wizard.ReviewboardQueryPage;
+import org.review_board.ereviewboard.ui.wizard.ReviewboardRepositorySettingsPage;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardConnectorUi extends AbstractRepositoryConnectorUi {
+
+    @Override
+    public String getConnectorKind() {
+        return ReviewboardCorePlugin.REPOSITORY_KIND;
+    }
+
+    @Override
+    public ITaskRepositoryPage getSettingsPage(TaskRepository taskRepository) {
+        return new ReviewboardRepositorySettingsPage(taskRepository);
+    }
+
+    @Override
+    public boolean hasSearchPage() {
+        return false;
+    }
+
+    @Override
+    public IWizard getNewTaskWizard(TaskRepository taskRepository, ITaskMapping taskSelection) {
+        ReviewboardRepositoryConnector connector = (ReviewboardRepositoryConnector) TasksUi
+                .getRepositoryManager().getRepositoryConnector(
+                        ReviewboardCorePlugin.REPOSITORY_KIND);
+        final ReviewboardClient client = connector.getClientManager().getClient(taskRepository);
+
+        return new NewReviewboardReviewRequestWizard(taskRepository, client);
+    }
+
+    @Override
+    public IWizard getQueryWizard(TaskRepository taskRepository, IRepositoryQuery queryToEdit) {
+        RepositoryQueryWizard wizard = new RepositoryQueryWizard(taskRepository);
+        wizard.addPage(new ReviewboardQueryPage(taskRepository, queryToEdit));
+        return wizard;
+    }
+
+    @Override
+    public String getTaskKindLabel(ITask task) {
+        return "Review Request";
+    }
+
+    @Override
+    public String getAccountCreationUrl(TaskRepository taskRepository) {
+        return taskRepository.getRepositoryUrl() + "/account/login/"; //$NON-NLS-1$
+    }
+
+    @Override
+    public String getAccountManagementUrl(TaskRepository taskRepository) {
+        return taskRepository.getRepositoryUrl() + "/account/preferences/"; //$NON-NLS-1$
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardConnectorUi.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiPlugin.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiPlugin.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiPlugin.java	(revision 0)
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.mylyn.tasks.ui.TaskRepositoryLocationUiFactory;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.osgi.framework.BundleContext;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardUiPlugin extends Plugin {
+
+    public static final String PLUGIN_ID = "org.review_board.ereviewboard.ui";
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        ReviewboardCorePlugin corePlugin = ReviewboardCorePlugin.getDefault();
+
+        assert corePlugin != null;
+        corePlugin.getConnector().setTaskRepositoryLocationFactory(
+                new TaskRepositoryLocationUiFactory());
+        TasksUi.getRepositoryManager().addListener(corePlugin.getConnector().getClientManager());
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiPlugin.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiUtil.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiUtil.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiUtil.java	(revision 0)
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ComboViewer;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public final class ReviewboardUiUtil {
+
+    private ReviewboardUiUtil() {
+        super();
+    }
+
+    public static List<String> getStringList(List<?> list) {
+        List<String> result = new ArrayList<String>();
+
+        for (Object string : list) {
+            result.add(string.toString());
+        }
+
+        return result;
+    }
+
+    public static void selectDefaultComboItem(ComboViewer comboViewer) {
+        if (comboViewer.getCombo().getItemCount() > 0 && comboViewer.getSelection().isEmpty()) {
+            comboViewer.getCombo().select(0);
+        }
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/ReviewboardUiUtil.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/dialog/CloseReviewRequestDialog.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/dialog/CloseReviewRequestDialog.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/dialog/CloseReviewRequestDialog.java	(revision 0)
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.dialog;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class CloseReviewRequestDialog extends Dialog {
+
+    public CloseReviewRequestDialog(Shell parentShell) {
+        super(parentShell);
+    }
+
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite composite = (Composite) super.createDialogArea(parent);
+
+        createRadioButton(composite, "Submitted");
+        createRadioButton(composite, "Discarded");
+        createRadioButton(composite, "Delete Permanently");
+
+        return composite;
+    }
+
+    private Button createRadioButton(Composite parent, String text) {
+        Button button = new Button(parent, SWT.RADIO);
+        button.setText(text);
+        return button;
+    }
+
+    @Override
+    protected void createButtonsForButtonBar(Composite parent) {
+        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+        createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+    }
+
+    @Override
+    protected Point getInitialSize() {
+        return new Point(300, 200);
+    }
+
+    protected void configureShell(Shell newShell) {
+        super.configureShell(newShell);
+        newShell.setText("Close review request");
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/dialog/CloseReviewRequestDialog.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/AbstractFormPagePart.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/AbstractFormPagePart.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/AbstractFormPagePart.java	(revision 0)
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.editor;
+
+import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public abstract class AbstractFormPagePart extends AbstractFormPart {
+
+    protected LocalResourceManager resources;
+
+    protected Font titleFont;
+
+    protected Color attributeNameColor;
+
+    public AbstractFormPagePart() {
+        super();
+        resources = new LocalResourceManager(JFaceResources.getResources());
+        titleFont = resources.createFont(FontDescriptor.createFrom("Sans", 13, SWT.NORMAL));
+        attributeNameColor = resources.createColor(new RGB(87, 80, 18));
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        resources.dispose();
+    }
+
+    public abstract Control createControl(Composite parent, FormToolkit toolkit);
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/AbstractFormPagePart.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorAttributesPart.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorAttributesPart.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorAttributesPart.java	(revision 0)
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.client.ReviewboardClientData;
+import org.review_board.ereviewboard.core.exception.ReviewboardException;
+import org.review_board.ereviewboard.core.model.ReviewGroup;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+import org.review_board.ereviewboard.core.model.User;
+import org.review_board.ereviewboard.core.util.ReviewboardUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewRequestEditorAttributesPart extends AbstractFormPagePart {
+
+    private Composite parentComposite;
+    private FormToolkit toolkit;
+
+    private Label sumbitterLabel;
+    private Label reviewersLabel;
+    private Text branchText;
+    private Text groupsText;
+    private Text bugsText;
+    private Text peopleText;
+    private Label changeNumLabel;
+    private Label repositoryLabel;
+    private Text descriptionText;
+    private Text testingDoneText;
+
+    private ReviewRequest reviewRequest;
+    private ReviewboardClient client;
+    private ReviewRequestEditorHeaderPart headerPart;
+
+    public ReviewRequestEditorAttributesPart(ReviewRequest reviewRequest, ReviewboardClient client,
+            ReviewRequestEditorHeaderPart headerPart) {
+        this.reviewRequest = reviewRequest;
+        this.client = client;
+        this.headerPart = headerPart;
+    }
+
+    @Override
+    public Control createControl(Composite parent, FormToolkit toolkit) {
+        this.toolkit = toolkit;
+
+        ExpandableComposite expandableComposite = toolkit.createExpandableComposite(parent,
+                ExpandableComposite.TWISTIE);
+        expandableComposite.setText("Attributes");
+        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).applyTo(expandableComposite);
+
+        parentComposite = new Composite(expandableComposite, SWT.NONE);
+        toolkit.adapt(parentComposite);
+        toolkit.paintBordersFor(parentComposite);
+        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(parentComposite);
+
+        expandableComposite.setClient(parentComposite);
+        expandableComposite.setExpanded(true);
+
+        createAttributeName("Submitter:");
+        sumbitterLabel = createLabelAttribute();
+
+        createAttributeName("Reviewers").setForeground(
+                parentComposite.getDisplay().getSystemColor(SWT.COLOR_BLACK));
+        reviewersLabel = createLabelAttribute();
+
+        createAttributeName("Branch:");
+        branchText = createTextAttribute();
+
+        createAttributeName("Groups");
+        groupsText = createTextAttribute();
+
+        createAttributeName("Bugs closed:");
+        bugsText = createTextAttribute();
+
+        createAttributeName("People:");
+        peopleText = createTextAttribute();
+
+        createAttributeName("Change number:");
+        changeNumLabel = createLabelAttribute();
+
+        createAttributeName("Repository:");
+        repositoryLabel = createLabelAttribute();
+
+        descriptionText = createMultiTextAttribute("Description:");
+        testingDoneText = createMultiTextAttribute("Testing done:");
+
+        Button updateAttributesButton = toolkit.createButton(parentComposite,
+                "Update attributes", SWT.NONE);
+        updateAttributesButton.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(final SelectionEvent e) {
+                try {
+                    ReviewRequest reviewRequest = getInput();
+                    client.updateReviewRequest(reviewRequest);
+                    setInput(reviewRequest);
+                } catch (ReviewboardException ex) {
+                    // TODO Auto-generated catch block
+                    ex.printStackTrace();
+                }
+            }
+        });
+        new Label(expandableComposite, SWT.NONE);
+        new Label(expandableComposite, SWT.NONE);
+        new Label(expandableComposite, SWT.NONE);
+
+        setInput(reviewRequest);
+
+        return expandableComposite;
+    }
+
+    private Text createMultiTextAttribute(String name) {
+        Label descriptionLabel = createAttributeName(name);
+        GridDataFactory.fillDefaults().span(4, 1).applyTo(descriptionLabel);
+
+        Text text = toolkit.createText(parentComposite, "", SWT.MULTI | SWT.WRAP
+                | SWT.V_SCROLL);
+        GridDataFactory.swtDefaults().span(4, 1).hint(700, 100).applyTo(text);
+
+        return text;
+    }
+
+    private Label createAttributeName(String name) {
+        Label label = toolkit.createLabel(parentComposite, name);
+        GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
+        label.setForeground(attributeNameColor);
+        return label;
+    }
+
+    private Label createLabelAttribute() {
+        return toolkit.createLabel(parentComposite, "");
+    }
+
+    private Text createTextAttribute() {
+        Text text = toolkit.createText(parentComposite, "");
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
+        return text;
+    }
+
+    public void setInput(ReviewRequest reviewRequest) {
+        sumbitterLabel.setText(reviewRequest.getSubmitter().getUsername());
+        branchText.setText(reviewRequest.getBranch());
+
+        bugsText.setText(ReviewboardUtil.unmarshallBugsClosed(reviewRequest.getBugsClosed()));
+        groupsText.setText(ReviewboardUtil.unmarshallTargetGroup(reviewRequest.getTargetGroups()));
+        peopleText.setText(ReviewboardUtil.unmarshallTargetPeople(reviewRequest.getTargetPeople()));
+
+        if (reviewRequest.getChangeNumber() == null) {
+            changeNumLabel.setText("None");
+        } else {
+            changeNumLabel.setText(String.valueOf(reviewRequest.getChangeNumber()));
+        }
+
+        repositoryLabel.setText(reviewRequest.getRepository().getName());
+        descriptionText.setText(reviewRequest.getDescription());
+        testingDoneText.setText(reviewRequest.getTestingDone());
+
+        headerPart.setSummary(reviewRequest.getSummary());
+    }
+
+    public ReviewRequest getInput() {
+        ReviewRequest reviewRequest = ReviewboardUtil.cloneEntity(this.reviewRequest);
+
+        reviewRequest.setBugsClosed(marshallBugsClosed(bugsText.getText()));
+        reviewRequest.setTargetGroups(marshallTargetGroups(groupsText.getText()));
+        reviewRequest.setTargetPeople(marshallTargetPeople(peopleText.getText()));
+
+        reviewRequest.setBranch(branchText.getText());
+        reviewRequest.setDescription(descriptionText.getText());
+        reviewRequest.setTestingDone(testingDoneText.getText());
+
+        reviewRequest.setSummary(headerPart.getSummary());
+
+        return reviewRequest;
+    }
+
+    private List<Integer> marshallBugsClosed(String bugsClosed) {
+        List<Integer> result = new ArrayList<Integer>();
+
+        for (String bugClosed : bugsClosed.split(",")) {
+            try {
+                int bug = Integer.parseInt(bugClosed.trim());
+                result.add(bug);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        return result;
+    }
+
+    private List<User> marshallTargetPeople(String targetPeople) {
+        List<User> result = new ArrayList<User>();
+        int index;
+
+        for (String username : targetPeople.split(",")) {
+            index = client.getClientData().getUsers().indexOf(new User(username.trim()));
+            if (index >= 0) {
+                result.add(client.getClientData().getUsers().get(index));
+            }
+        }
+
+        return result;
+    }
+
+    private List<ReviewGroup> marshallTargetGroups(String targetGroups) {
+        List<ReviewGroup> result = new ArrayList<ReviewGroup>();
+        int index;
+
+        for (String group : targetGroups.split(",")) {
+            index = client.getClientData().getGroups().indexOf(new ReviewGroup(group.trim()));
+            if (index >= 0) {
+                result.add(client.getClientData().getGroups().get(index));
+            }
+        }
+
+        return result;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorAttributesPart.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorHeaderPart.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorHeaderPart.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorHeaderPart.java	(revision 0)
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.editor;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewRequestEditorHeaderPart extends AbstractFormPagePart {
+
+    private TaskEditor editor;
+
+    private Composite parentComposite;
+
+    private FormToolkit toolkit;
+
+    private Text summaryText;
+
+    private Label lblUpdatedWeek;
+
+    public ReviewRequestEditorHeaderPart(TaskEditor editor) {
+        this.editor = editor;
+    }
+
+    private ITask getTask() {
+        return editor.getTaskEditorInput().getTask();
+    }
+
+    @Override
+    public Control createControl(Composite parent, FormToolkit toolkit) {
+        this.toolkit = toolkit;
+
+        parentComposite = toolkit.createComposite(parent);
+        toolkit.paintBordersFor(parentComposite);
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parentComposite);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(parentComposite);
+
+        createSummaryLabel();
+        createSummaryText();
+        createLastUpdatedLabel();
+
+        Label label = toolkit.createSeparator(parent, SWT.HORIZONTAL);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(label);
+
+        return parentComposite;
+    }
+
+    private void createSummaryLabel() {
+        Label lblSummary = toolkit.createLabel(parentComposite, "Summary:");
+        GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(lblSummary);
+        lblSummary.setFont(titleFont);
+        lblSummary.setForeground(attributeNameColor);
+    }
+
+    private void createSummaryText() {
+        summaryText = toolkit.createText(parentComposite, getTask().getSummary());
+        GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).hint(500, 15).applyTo(
+                summaryText);
+        summaryText.setFont(titleFont);
+    }
+
+    private void createLastUpdatedLabel() {
+        lblUpdatedWeek = toolkit.createLabel(parentComposite, NLS.bind("Updated on {0}", getTask()
+                .getModificationDate()));
+        GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).span(2, 1).applyTo(
+                lblUpdatedWeek);
+        lblUpdatedWeek.setForeground(attributeNameColor);
+    }
+
+    public String getSummary() {
+        return summaryText.getText();
+    }
+
+    public void setSummary(String summary) {
+        summaryText.setText(summary);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorHeaderPart.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPage.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPage.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPage.java	(revision 0)
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
+import org.eclipse.mylyn.tasks.ui.editors.TaskFormPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+import org.review_board.ereviewboard.core.ReviewboardRepositoryConnector;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+import org.review_board.ereviewboard.ui.ReviewboardUiPlugin;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewRequestEditorPage extends TaskFormPage {
+
+    private TaskEditor editor;
+
+    private ScrolledForm form;
+
+    private FormToolkit toolkit;
+
+    private Composite editorComposite;
+
+    private List<AbstractFormPagePart> parts;
+
+    private ReviewRequest reviewRequest;
+
+    private ReviewboardClient client;
+
+    public ReviewRequestEditorPage(TaskEditor editor, String title) {
+        super(editor, ReviewboardCorePlugin.REPOSITORY_KIND, title);
+        this.editor = editor;
+        parts = new ArrayList<AbstractFormPagePart>();
+
+        ReviewboardRepositoryConnector connector = ReviewboardCorePlugin.getDefault()
+                .getConnector();
+        client = connector.getClientManager().getClient(getTaskRepository());
+    }
+
+    @Override
+    public TaskEditor getEditor() {
+        return (TaskEditor) super.getEditor();
+    }
+
+    private ITask getTask() {
+        return getEditor().getTaskEditorInput().getTask();
+    }
+
+    private TaskRepository getTaskRepository() {
+        return getEditor().getTaskEditorInput().getTaskRepository();
+    }
+
+    @Override
+    protected void fillToolBar(IToolBarManager toolBarManager) {
+        // TODO Auto-generated method stub
+        super.fillToolBar(toolBarManager);
+    }
+
+    @Override
+    protected void createFormContent(IManagedForm managedForm) {
+        super.createFormContent(managedForm);
+        form = managedForm.getForm();
+        toolkit = managedForm.getToolkit();
+        editorComposite = form.getBody();
+
+        // TODO consider using TableWrapLayout, it makes resizing much faster
+        GridLayout editorLayout = new GridLayout();
+        editorComposite.setLayout(editorLayout);
+        editorComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        Display.getCurrent().asyncExec(new Runnable() {
+            public void run() {
+                downloadReviewRequestAndRefresh();
+            }
+        });
+    }
+
+    private void createFormParts() {
+        ReviewRequestEditorHeaderPart headerPart = new ReviewRequestEditorHeaderPart(editor);
+        parts.add(headerPart);
+        if (reviewRequest != null) {
+            parts.add(new ReviewRequestEditorAttributesPart(reviewRequest, client, headerPart));
+        }
+    }
+
+    private void clearFormContent() {
+        for (AbstractFormPagePart part : parts) {
+            getManagedForm().removePart(part);
+        }
+        parts.clear();
+
+        // remove all of the old widgets so that we can redraw the editor
+        for (Control child : editorComposite.getChildren()) {
+            child.dispose();
+        }
+    }
+
+    private void setBusy(boolean busy) {
+        getEditor().showBusy(busy);
+    }
+
+    private void downloadReviewRequestAndRefresh() {
+        Job job = new Job(NLS.bind("Retrieving review request {0}...", getTask().getTaskId())) {
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                monitor.subTask("Retrieving review request");
+                try {
+                    reviewRequest = client.getReviewRequest(Integer.valueOf(getTask().getTaskId()));
+                } catch (Exception e) {
+                    return new Status(IStatus.ERROR, ReviewboardUiPlugin.PLUGIN_ID, e.getMessage());
+                }
+                return new Status(IStatus.OK, ReviewboardUiPlugin.PLUGIN_ID, null);
+            }
+        };
+        job.addJobChangeListener(new JobChangeAdapter() {
+            @Override
+            public void done(final IJobChangeEvent event) {
+                Display.getDefault().asyncExec(new Runnable() {
+                    public void run() {
+                        reviewRequestUpdateCompleted();
+                    }
+                });
+            }
+        });
+        job.schedule();
+        setBusy(true);
+    }
+
+    private void reviewRequestUpdateCompleted() {
+        setBusy(false);
+        createInitialFormContent();
+    }
+
+    private void createInitialFormContent() {
+        clearFormContent();
+        createFormParts();
+
+        for (AbstractFormPagePart part : parts) {
+            getManagedForm().addPart(part);
+            part.initialize(getManagedForm());
+            part.createControl(editorComposite, toolkit);
+        }
+
+        form.layout(true, true);
+        form.reflow(true);
+        form.setRedraw(true);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPage.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPageFactory.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPageFactory.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPageFactory.java	(revision 0)
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.editor;
+
+import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
+import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPageFactory;
+import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
+import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewRequestEditorPageFactory extends AbstractTaskEditorPageFactory {
+
+    private static final String TITLE = "Reviewboard";
+
+    @Override
+    public boolean canCreatePageFor(TaskEditorInput input) {
+        if (input.getTask().getConnectorKind().equals(ReviewboardCorePlugin.REPOSITORY_KIND)) {
+            return true;
+        } else if (TasksUiUtil.isOutgoingNewTask(input.getTask(),
+                ReviewboardCorePlugin.REPOSITORY_KIND)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Image getPageImage() {
+        return null;
+    }
+
+    @Override
+    public String getPageText() {
+        return TITLE;
+    }
+
+    @Override
+    public IFormPage createPage(TaskEditor parentEditor) {
+        return new ReviewRequestEditorPage(parentEditor, TITLE);
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/editor/ReviewRequestEditorPageFactory.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/widget/CFileChooser.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/widget/CFileChooser.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/widget/CFileChooser.java	(revision 0)
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.widget;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class CFileChooser extends Composite {
+
+    private Text text;
+
+    public CFileChooser(Composite parent, int style) {
+        super(parent, style);
+        setLayout(new GridLayout(2, false));
+
+        text = new Text(this, SWT.BORDER);
+        text.setEnabled(false);
+        text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+        text.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                notifyListeners(SWT.Modify, event);
+            }
+        });
+
+        final Button browseButton = new Button(this, SWT.NONE);
+        browseButton.setText("Browse...");
+        browseButton.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event event) {
+                FileDialog fileDialog = new FileDialog(getShell());
+                fileDialog.setFilterExtensions(new String[] {
+                        "Diffs/Patches", "All Files"
+                });
+                fileDialog.setFilterExtensions(
+                        new String[] { "*.diff; *.patch", "*.*" });
+                String result = fileDialog.open();
+                if (result != null) {
+                    text.setText(result);
+                }
+            }
+        });
+    }
+
+    public IFile getFile() {
+        if (text.getText() != null) {
+            IPath path = new Path(text.getText());
+            return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+        }
+        return null;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/widget/CFileChooser.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewDiffPage.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewDiffPage.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewDiffPage.java	(revision 0)
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.wizard;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.review_board.ereviewboard.ui.widget.CFileChooser;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class NewDiffPage extends WizardPage {
+
+    private static final String TITLE = "New Diff";
+
+    private static final String DESCRIPTION = "Enter data for new diff.";
+
+    private Text baseDiffPathText;
+    private CFileChooser diffFileChooser;
+    private CFileChooser parentDiffFileChooser;
+
+    protected NewDiffPage() {
+        super(TITLE);
+
+        setTitle(TITLE);
+        setDescription(DESCRIPTION);
+    }
+
+    public void createControl(Composite parent) {
+        Composite composite = new Composite(parent, SWT.NULL);
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);
+        setControl(composite);
+
+        GridDataFactory gridDataFactory = GridDataFactory.fillDefaults()
+                .align(SWT.FILL, SWT.CENTER).grab(true, false).copy();
+
+        final Label baseDiffPathLabel = new Label(composite, SWT.NONE);
+        baseDiffPathLabel.setText("Base Diff Path:");
+
+        baseDiffPathText = new Text(composite, SWT.BORDER);
+        gridDataFactory.applyTo(baseDiffPathText);
+        baseDiffPathText.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                setPageComplete(isPageComplete());
+            }
+        });
+
+        final Label diffLabel = new Label(composite, SWT.NONE);
+        diffLabel.setText("Diff:");
+
+        diffFileChooser = new CFileChooser(composite, SWT.NONE);
+        gridDataFactory.applyTo(diffFileChooser);
+        diffFileChooser.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                setPageComplete(isPageComplete());
+            }
+        });
+
+        final Label parentDiffLabel = new Label(composite, SWT.NONE);
+        parentDiffLabel.setText("Parent diff:");
+
+        diffFileChooser = new CFileChooser(composite, SWT.NONE);
+        gridDataFactory.applyTo(diffFileChooser);
+    }
+
+    @Override
+    public boolean isPageComplete() {
+        return (baseDiffPathText.getText().length() > 0) && (diffFileChooser.getFile() != null);
+    }
+
+    public String getBaseDiffPath() {
+        return baseDiffPathText.getText();
+    }
+
+    public IFile getDiff() {
+        return diffFileChooser.getFile();
+    }
+
+    public IFile getParentDiff() {
+        return parentDiffFileChooser.getFile();
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewDiffPage.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewRequestPage.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewRequestPage.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewRequestPage.java	(revision 0)
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.wizard;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.review_board.ereviewboard.core.client.ReviewboardClientData;
+import org.review_board.ereviewboard.core.model.ReviewRequest;
+import org.review_board.ereviewboard.ui.ReviewboardUiUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class NewReviewRequestPage extends WizardPage {
+
+    private static final String TITLE = "New Review Request";
+
+    private static final String DESCRIPTION = "Enter data for new review request.";
+
+    private Combo repositoryCombo;
+    private Text changeNumText;
+
+    private ReviewboardClientData clientData;
+
+    public NewReviewRequestPage(ReviewboardClientData clientData) {
+        super(TITLE);
+        this.clientData = clientData;
+
+        setTitle(TITLE);
+        setDescription(DESCRIPTION);
+    }
+
+    public void createControl(Composite parent) {
+        Composite composite = new Composite(parent, SWT.NULL);
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);
+        setControl(composite);
+
+        GridDataFactory gridDataFactory = GridDataFactory.fillDefaults()
+                .align(SWT.FILL, SWT.CENTER).grab(true, false).copy();
+
+        final Label label = new Label(composite, SWT.NONE);
+        label.setText("Repository:");
+
+        final ComboViewer comboViewer = new ComboViewer(composite, SWT.BORDER | SWT.READ_ONLY);
+        comboViewer.setContentProvider(new ArrayContentProvider());
+        repositoryCombo = comboViewer.getCombo();
+        gridDataFactory.applyTo(repositoryCombo);
+        comboViewer.setInput(ReviewboardUiUtil.getStringList(clientData.getRepositories()));
+        repositoryCombo.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                getContainer().updateButtons();
+            }
+        });
+
+        final Label changeNumLabel = new Label(composite, SWT.NONE);
+        changeNumLabel.setText("Change number:");
+
+        changeNumText = new Text(composite, SWT.BORDER);
+        gridDataFactory.applyTo(changeNumText);
+    }
+
+    @Override
+    public boolean isPageComplete() {
+        return repositoryCombo.getSelectionIndex() >= 0;
+    }
+
+    public ReviewRequest getReviewRequest() {
+        ReviewRequest reviewRequest = new ReviewRequest();
+
+        reviewRequest.setRepository(clientData.getRepositories().get(
+                repositoryCombo.getSelectionIndex()));
+        if (changeNumText.getText().length() > 0) {
+            reviewRequest.setChangeNumber(Integer.parseInt(changeNumText.getText()));
+        }
+
+        return reviewRequest;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewRequestPage.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewboardReviewRequestWizard.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewboardReviewRequestWizard.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewboardReviewRequestWizard.java	(revision 0)
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.wizard;
+
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITaskMapping;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
+import org.eclipse.mylyn.tasks.ui.wizards.NewTaskWizard;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.INewWizard;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.exception.ReviewboardException;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class NewReviewboardReviewRequestWizard extends NewTaskWizard implements INewWizard {
+
+    private ReviewboardClient client;
+
+    private NewReviewRequestPage newReviewRequestWizardPage;
+
+    public NewReviewboardReviewRequestWizard(TaskRepository taskRepository, ReviewboardClient client) {
+        super(taskRepository, null);
+        this.client = client;
+    }
+
+    @Override
+    public void addPages() {
+        newReviewRequestWizardPage = new NewReviewRequestPage(client.getClientData());
+        addPage(newReviewRequestWizardPage);
+    }
+
+    @Override
+    public void createPageControls(Composite pageContainer) {
+            super.createPageControls(pageContainer);
+    }
+
+    @Override
+    public boolean performFinish() {
+        try {
+            client.newReviewRequest(newReviewRequestWizardPage.getReviewRequest());
+        } catch (ReviewboardException e) {
+            throw new RuntimeException(e);
+        }
+        return true;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/NewReviewboardReviewRequestWizard.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardQueryPage.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardQueryPage.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardQueryPage.java	(revision 0)
@@ -0,0 +1,433 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.wizard;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.layout.RowLayoutFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.progress.IProgressService;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+import org.review_board.ereviewboard.core.ReviewboardRepositoryConnector;
+import org.review_board.ereviewboard.core.client.ReviewboardClient;
+import org.review_board.ereviewboard.core.client.ReviewboardClientData;
+import org.review_board.ereviewboard.core.model.AllReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.FromUserReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.GroupReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.Repository;
+import org.review_board.ereviewboard.core.model.RepositoryReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.ReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.ReviewRequestStatus;
+import org.review_board.ereviewboard.core.model.StatusReviewRequestQuery;
+import org.review_board.ereviewboard.core.model.ToUserReviewRequestQuery;
+import org.review_board.ereviewboard.ui.ReviewboardUiUtil;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardQueryPage extends AbstractRepositoryQueryPage {
+
+    private static final String TITLE = "Enter query parameters";
+
+    private static final String DESCRIPTION = "Select options to create a query";
+
+    private static final String TITLE_QUERY_TITLE = "Query title";
+
+    private ReviewboardClient client;
+
+    private IRepositoryQuery query;
+
+    private Text titleText;
+
+    private ReviewRequestQuery reviewRequestQuery;
+
+    private ReviewRequestStatus status;
+
+    private String changeNum = "";
+
+    private RowLayout defaultRowLayout;
+
+    private ComboViewer groupCombo;
+    private ComboViewer fromUserCombo;
+    private ComboViewer toUserCombo;
+    private ComboViewer repositoryCombo;
+
+    public ReviewboardQueryPage(TaskRepository taskRepository, IRepositoryQuery query) {
+        super(TITLE, taskRepository, query);
+
+        this.query = query;
+
+        ReviewboardRepositoryConnector connector = (ReviewboardRepositoryConnector) TasksUi
+                .getRepositoryManager().getRepositoryConnector(
+                        ReviewboardCorePlugin.REPOSITORY_KIND);
+        client = connector.getClientManager().getClient(getTaskRepository());
+
+        defaultRowLayout = new RowLayout();
+        defaultRowLayout.center = true;
+        defaultRowLayout.wrap = false;
+
+        setTitle(TITLE);
+        setDescription(DESCRIPTION);
+    }
+
+    public ReviewboardQueryPage(TaskRepository repository) {
+        this(repository, null);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        super.setVisible(visible);
+        if (visible) {
+            updateRepositoryData(false);
+
+            Display.getDefault().asyncExec(new Runnable() {
+                public void run() {
+                    if (query != null) {
+                        restoreQuery(query);
+                    } else {
+                        reviewRequestQuery = new AllReviewRequestQuery(ReviewRequestStatus.PENDING);
+                    }
+                }
+            });
+        }
+    }
+
+    private void updateRepositoryData(final boolean force) {
+        if (force || !client.hasRepositoryData()) {
+            try {
+                IRunnableWithProgress runnable = new IRunnableWithProgress() {
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException,
+                            InterruptedException {
+                        try {
+                            client.updateRepositoryData(force, monitor);
+                        } catch (Exception e) {
+                            throw new InvocationTargetException(e);
+                        }
+                    }
+                };
+
+                if (getContainer() != null) {
+                    getContainer().run(true, true, runnable);
+                } else if (getSearchContainer() != null) {
+                    getSearchContainer().getRunnableContext().run(true, true, runnable);
+                } else {
+                    IProgressService service = PlatformUI.getWorkbench().getProgressService();
+                    service.busyCursorWhile(runnable);
+                }
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            } catch (InterruptedException e) {
+                return;
+            }
+        }
+
+        ReviewboardClientData clientData = client.getClientData();
+        groupCombo.setInput(ReviewboardUiUtil.getStringList(clientData.getGroups()));
+        repositoryCombo.setInput(ReviewboardUiUtil.getStringList(clientData.getRepositories()));
+
+        // TODO replace with another control
+        toUserCombo.setInput(ReviewboardUiUtil.getStringList(clientData.getUsers()));
+        fromUserCombo.setInput(ReviewboardUiUtil.getStringList(clientData.getUsers()));
+
+        ReviewboardUiUtil.selectDefaultComboItem(groupCombo);
+        ReviewboardUiUtil.selectDefaultComboItem(toUserCombo);
+        ReviewboardUiUtil.selectDefaultComboItem(fromUserCombo);
+        ReviewboardUiUtil.selectDefaultComboItem(repositoryCombo);
+    }
+
+    private void restoreQuery(IRepositoryQuery query) {
+        titleText.setText(query.getSummary());
+        changeNum = query.getAttribute("changeNum");
+        reviewRequestQuery = StatusReviewRequestQuery.fromQueryString(query.getUrl());
+    }
+
+    @Override
+    public void applyTo(IRepositoryQuery query) {
+        query.setSummary(getQueryTitle());
+        query.setUrl(reviewRequestQuery.getQuery());
+        query.setAttribute("changeNum", changeNum);
+    }
+
+    @Override
+    public String getQueryTitle() {
+        if (titleText == null) {
+            return "<search>";
+        } else {
+            return titleText.getText();
+        }
+    }
+
+    @Override
+    public boolean canFlipToNextPage() {
+        return false;
+    }
+
+    @Override
+    public boolean isPageComplete() {
+        return validate();
+    }
+
+    private boolean validate() {
+        boolean valid = true;
+        if (reviewRequestQuery instanceof RepositoryReviewRequestQuery) {
+            RepositoryReviewRequestQuery repositoryQuery = (RepositoryReviewRequestQuery) reviewRequestQuery;
+            valid = repositoryQuery.isValid();
+        }
+
+        return (titleText != null && titleText.getText().length() > 0) && valid;
+    }
+
+    public void createControl(Composite parent) {
+        Composite control = new Composite(parent, SWT.NONE);
+        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(control);
+        GridDataFactory.fillDefaults().applyTo(control);
+
+        createTitleGroup(control);
+
+        Composite parentRadioComposite = new Composite(control, SWT.NONE);
+        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(parentRadioComposite);
+        GridDataFactory.fillDefaults().span(4, 1).applyTo(parentRadioComposite);
+
+        Composite radioComposite = new Composite(parentRadioComposite, SWT.NONE);
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(radioComposite);
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(radioComposite);
+
+        Button all = createRadioButton(radioComposite, "All");
+        all.setSelection(true);
+        all.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event event) {
+                reviewRequestQuery = new AllReviewRequestQuery(status);
+                getContainer().updateButtons();
+            }
+        });
+        createRadioComposite(radioComposite);
+
+        Composite groupComposite = createRadioCompositeWithCombo(radioComposite, "With group");
+        groupCombo = createGroupCombo(groupComposite);
+
+        Composite fromUserComposite = createRadioCompositeWithCombo(radioComposite, "From the user");
+        fromUserCombo = createFromUserCombo(fromUserComposite);
+
+        Composite toUserComposite = createRadioCompositeWithCombo(radioComposite, "To the user");
+        toUserCombo = createToUserCombo(toUserComposite);
+
+        Composite repositoryComposite = createRadioCompositeWithCombo(radioComposite, "From repository");
+        repositoryCombo = createRepositoryCombo(repositoryComposite);
+        Label changeNumLabel = new Label(repositoryComposite, SWT.NONE);
+        changeNumLabel.setText("with change number:");
+        Text changeNumText = new Text(repositoryComposite, SWT.BORDER);
+        changeNumText.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                changeNum = ((Text) event.widget).getText();
+                event.widget = repositoryCombo.getCombo();
+                repositoryCombo.getCombo().notifyListeners(SWT.Modify, event);
+                getContainer().updateButtons();
+            }
+        });
+
+        Composite statusComposite = new Composite(control, SWT.NONE);
+        RowLayoutFactory.createFrom(defaultRowLayout).applyTo(statusComposite);
+
+        Label statusLabel = new Label(statusComposite, SWT.NONE);
+        statusLabel.setText("With Status");
+        ComboViewer statusCombo = createCombo(statusComposite);
+        for (ReviewRequestStatus status : ReviewRequestStatus.values()) {
+            statusCombo.add(status.getDisplayname());
+        }
+        statusCombo.getCombo().select(0);
+        statusCombo.getCombo().addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                if (reviewRequestQuery != null) {
+                    reviewRequestQuery.setStatus(ReviewRequestStatus.valueOf(((Combo) event.widget)
+                            .getText().toUpperCase()));
+                }
+            }
+        });
+
+        setControl(control);
+    }
+
+    private Composite createRadioComposite(Composite parent) {
+        final Composite composite = new Composite(parent, SWT.NONE);
+        RowLayoutFactory.createFrom(defaultRowLayout).applyTo(composite);
+
+        return composite;
+    }
+
+    private Composite createRadioCompositeWithCombo(final Composite parent, String text) {
+        Button button = createRadioButton(parent, text);
+        final Composite composite = createRadioComposite(parent);
+        composite.setEnabled(false);
+
+        button.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event event) {
+                composite.setEnabled(!composite.getEnabled());
+                composite.notifyListeners(SWT.Modify, event);
+            }
+        });
+
+        return composite;
+    }
+
+    private ComboViewer createCombo(Composite parent) {
+        final ComboViewer combo = new ComboViewer(parent, SWT.DROP_DOWN | SWT.BORDER
+                | SWT.READ_ONLY);
+        combo.setContentProvider(new ArrayContentProvider());
+
+        parent.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                event.widget = combo.getCombo();
+                combo.getCombo().notifyListeners(SWT.Modify, event);
+            }
+        });
+
+        return combo;
+    }
+
+    private ComboViewer createGroupCombo(Composite parent) {
+        ComboViewer combo = createCombo(parent);
+
+        combo.getCombo().addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                reviewRequestQuery = new GroupReviewRequestQuery(status, ((Combo) event.widget)
+                        .getText());
+                getContainer().updateButtons();
+            }
+        });
+
+        return combo;
+    }
+
+    private ComboViewer createFromUserCombo(Composite parent) {
+        ComboViewer combo = createCombo(parent);
+
+        combo.getCombo().addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                reviewRequestQuery = new FromUserReviewRequestQuery(status, ((Combo) event.widget)
+                        .getText());
+                getContainer().updateButtons();
+            }
+        });
+
+        return combo;
+    }
+
+    private ComboViewer createToUserCombo(Composite parent) {
+        ComboViewer combo = createCombo(parent);
+        combo.setContentProvider(new ArrayContentProvider());
+
+        combo.getCombo().addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                reviewRequestQuery = new ToUserReviewRequestQuery(status, ((Combo) event.widget)
+                        .getText());
+                getContainer().updateButtons();
+            }
+        });
+
+        return combo;
+    }
+
+    private ComboViewer createRepositoryCombo(Composite parent) {
+        ComboViewer combo = createCombo(parent);
+
+        combo.getCombo().addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                Repository repository = client.getClientData().getRepositories().get(
+                        ((Combo) event.widget).getSelectionIndex());
+
+                int changeNumInt = 0;
+                try {
+                    changeNumInt = Integer.valueOf(changeNum);
+                } catch (NumberFormatException e) {
+                    // ignore
+                }
+
+                reviewRequestQuery = new RepositoryReviewRequestQuery(status, repository.getId(),
+                        changeNumInt);
+                getContainer().updateButtons();
+            }
+        });
+
+        return combo;
+    }
+
+    private Button createRadioButton(Composite parent, String text) {
+        Button radioButton = new Button(parent, SWT.RADIO);
+        radioButton.setText(text);
+        return radioButton;
+    }
+
+    private void createTitleGroup(Composite control) {
+        if (inSearchContainer()) {
+            return;
+        }
+
+        Label titleLabel = new Label(control, SWT.NONE);
+        titleLabel.setText(TITLE_QUERY_TITLE);
+
+        titleText = new Text(control, SWT.BORDER);
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(titleText);
+        titleText.addListener(SWT.Modify, new Listener() {
+            public void handleEvent(Event event) {
+                getContainer().updateButtons();
+            }
+        });
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardQueryPage.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardRepositorySettingsPage.java
===================================================================
--- ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardRepositorySettingsPage.java	(revision 0)
+++ ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardRepositorySettingsPage.java	(revision 0)
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2009 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Mylyn project committers, Atlassian, Sven Krzyzak
+ *******************************************************************************/
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Knittig
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributors:
+ *     Markus Knittig - adapted Trac, Redmine & Atlassian implementations for
+ *                      Review Board
+ *******************************************************************************/
+package org.review_board.ereviewboard.ui.wizard;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositorySettingsPage;
+import org.eclipse.swt.widgets.Composite;
+import org.review_board.ereviewboard.core.ReviewboardCorePlugin;
+
+/**
+ * @author Markus Knittig
+ *
+ */
+public class ReviewboardRepositorySettingsPage extends AbstractRepositorySettingsPage {
+
+    private static final String TITLE = "Reviewboard Repository Settings";
+
+    private static final String DESCRIPTION = "Example: reviews.your-domain.org";
+
+    private String checkedUrl = null;
+
+    public ReviewboardRepositorySettingsPage(TaskRepository taskRepository) {
+        super(TITLE, DESCRIPTION, taskRepository);
+
+        setNeedsAnonymousLogin(false);
+        setNeedsEncoding(false);
+        setNeedsTimeZone(false);
+        setNeedsAdvanced(false);
+        setNeedsValidation(true);
+    }
+
+    @Override
+    public void createControl(Composite parent) {
+        super.createControl(parent);
+        checkedUrl = getRepositoryUrl();
+    }
+
+    @Override
+    public boolean isPageComplete() {
+        return super.isPageComplete() && checkedUrl != null
+                && checkedUrl.equals(getRepositoryUrl());
+    }
+
+    @Override
+    protected void createAdditionalControls(Composite parent) {
+        // nothing to do yet
+
+    }
+
+    @Override
+    public String getConnectorKind() {
+        return ReviewboardCorePlugin.REPOSITORY_KIND;
+    }
+
+    @Override
+    protected Validator getValidator(final TaskRepository repository) {
+        return new Validator() {
+            @Override
+            public void run(IProgressMonitor monitor) throws CoreException {
+                ReviewboardRepositorySettingsPage.this.checkedUrl = repository.getRepositoryUrl();
+            }
+        };
+    }
+
+    @Override
+    protected boolean isValidUrl(String url) {
+        if ((url.startsWith(URL_PREFIX_HTTPS) || url.startsWith(URL_PREFIX_HTTP))
+                && !url.endsWith("/")) {
+            try {
+                new URL(url);
+                return true;
+            } catch (MalformedURLException e) {
+                // ignore
+            }
+        }
+
+        return false;
+    }
+
+}

Property changes on: ereviewboard/org.review_board.ereviewboard.ui/src/org/review_board/ereviewboard/ui/wizard/ReviewboardRepositorySettingsPage.java
___________________________________________________________________
Added: svn:eol-style
   + native

