merge trunk to common sl branch

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1691843 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..4824b80
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1

+encoding/<project>=UTF-8

diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 7f78832..b5af816 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -152,6 +152,7 @@
 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_lambda_body=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
@@ -197,6 +198,7 @@
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_label=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_after_type_annotation=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
@@ -244,6 +246,7 @@
 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_lambda_arrow=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
@@ -321,6 +324,7 @@
 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_lambda_arrow=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
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
index a38e1bf..4ad8c93 100644
--- a/.settings/org.eclipse.jdt.ui.prefs
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -1,12 +1,75 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Apache POI
+cleanup_settings_version=2
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false
 formatter_profile=_Apache POI
 formatter_settings_version=12
 org.eclipse.jdt.ui.exception.name=e
 org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
 org.eclipse.jdt.ui.javadoc=false
 org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=10
 org.eclipse.jdt.ui.overrideannotation=false
+org.eclipse.jdt.ui.staticondemandthreshold=10
 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 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\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n *\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   Licensed to the Apache Software Foundation (ASF) under one or more\n   contributor license agreements.  See the NOTICE file distributed with\n   this work for additional information regarding copyright ownership.\n   The ASF licenses this file to You under the Apache License, Version 2.0\n   (the "License"); you may not use this file except in compliance with\n   the License.  You may obtain a copy of the License at\n\n       http\://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an "AS IS" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\= */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\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\="false" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n *\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\="true" 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></templates>
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
@@ -21,10 +84,12 @@
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=true
 sp_cleanup.correct_indentation=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
@@ -40,6 +105,7 @@
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=false
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
@@ -53,10 +119,13 @@
 sp_cleanup.remove_unused_private_types=true
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
 sp_cleanup.use_blocks=true
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
diff --git a/.settings/org.moreunit.prefs b/.settings/org.moreunit.prefs
new file mode 100644
index 0000000..659afaf
--- /dev/null
+++ b/.settings/org.moreunit.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1

+org.moreunit.preferences.version=2

+org.moreunit.unitsourcefolder=ApachePOI\:src/java\:ApachePOI\:src/testcases\#ApachePOI\:src/java\:ApachePOI\:src/ooxml/testcases\#ApachePOI\:src/java\:ApachePOI\:src/scratchpad/testcases\#ApachePOI\:src/java\:ApachePOI\:src/excelant/testcases\#ApachePOI\:src/java\:ApachePOI\:src/integrationtest

+org.moreunit.useprojectsettings=true

diff --git a/KEYS b/KEYS
index 340f850..6e9b6ca 100644
--- a/KEYS
+++ b/KEYS
@@ -1796,3 +1796,348 @@
 FZwpzgut7DanaPcCDk7LMBbntaJwRC72M0qcj16SUAdAuGt1yQ==
 =0DjT
 -----END PGP PUBLIC KEY BLOCK-----
+
+pub   4096R/B4812553 2014-02-26 [expires: 2019-02-25]
+uid                  David North <david@dnorth.net>
+uid                  David North (Oxford CompSoc) <north@ox.compsoc.net>
+uid                  David North (ASF Committer ID) <dnorth@apache.org>
+
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBFMOLVsBEADW2N1bQ6GFDDSbC+IKggdS/lwhaEo5Av4Z5B2es83A43boyJZ1
+bn9xfd5TriHubI6VBgjbuB0peoCZye3PzEz9cfZYXsPiAqZngWk95or0N+vwrGoI
+9gJM6aBYjE06fxHZRTAi4ADPLW5sV0bT230/u1xpqg1lcko5eGV5sAjI9HaVdfvR
+68gQdNVK6TciOeM2EQcTHlRd8D9D2/XTp9aCFynNaFoKmBTOsc+VlczmIgd+1jzW
+qWcaGTkEtZKzAxUfxlWgO0xHjs3H4CGqtWWCqj8W1alkwIVHBeXIwHDoHlbmkXok
+65jfeQd9tWzTHGXETU7bBbxksbwRlrJrutgolLW+/v9F1je2aG/BKMwOLjF7dk8+
+gvSKlu4PwoItGN0qraWsqAGDR4/bWLihqPluW+pUL544li702DUeZiVxFEb22yDb
+p2oWdFafEFhQz4FxRCam/4bfVt6bGLGE8GEd1jeahgmpkIAcbAoI9UOFAVaoSWFv
+AqYphVfONeZz7MMIcNlyHth5VAvQQF7/uBWCsNtlvBtVirR+nis+eEwoNRDwYx3N
+OKu1GTFPMMHUauB0ORD2ywsFQkIjDbnQMNhwQoC49bs46vCusBb42qmOpjP0viVs
+qGI3Ae78F4KEBpa5AVbYRbbicOPeV/tRrHFWMyXmH312898j29qO57e+awARAQAB
+tB5EYXZpZCBOb3J0aCA8ZGF2aWRAZG5vcnRoLm5ldD6JAkAEEwEIACoCGwMFCQlm
+AYAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAlMOL4ECGQEACgkQ+bj6w7SBJVML
+Mg//To6EADRjfp11ZGu3cARitfx67276xAkt017sxw76LBzHoF60RtPjcRBBRCYk
+0P1URdip6nC2M7Ol151YdTUIfKNWDRzAUVgpWrGfUIRPUgClyO2boTijblS3heZS
+gCKz9x3WwRn5elR3Qf6u/wZGIuHBjmh9Jwoa/c6G6ikIoLjoUvXBWR53FlLIpHIF
+/q6mzwhXdCwohDsfDI7ckSuSv5yMJsYLZRpEKB3zLgWo4CQP6edaewBd0bVb/Uzy
+/5aeolwEfwoNSJ2J4+tQ39U1vxPr1NLEALNl4qW4Gn2fSACnWyEjDHrLltDvolU/
+iLXjgb//9ge93vZUfZmH6vPkrt4TzOfar4wLHTgiEX8nKaOwiMU72wgSL1DLJgry
+udf0zSIYDldm/Wy4ggywd/mSyp4oWR3pJFI926CyiQrnA4fSxKrE3yI4Pm5kZNBM
+5fhDwtPEtp4F/7kLxGK6MCxyeL94x9QnZdp4FHyRcO3XCCMhfAKT3qLiuHpTiNOt
+mOu3Ea1DsEVbSOw+gJzqEZN2ruB8z9DsOxNxlLsdW+sSQRSNgErnLlBLlkXpSawB
+imhbwfOHKqZ6eoEqz9ufbrJjIkOEDbIbW93hpyG7zdKSkKsXLR9HbOZ7kgMgzPVi
+KNAhc7axmvps55Jx7aXP7G+8c9d8iWhuwD9MemqvhRKyzeeJAj0EEwEIACcFAlMO
+LVsCGwMFCQlmAYAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ+bj6w7SBJVPR
+6A/9Gk3J6BV0IPuybnmxrkKUicPsIoXgRnzU9LF2TIC6mYJBjb3Tllw0kahsTwLa
+vfXEEk971zushOUH/z/wLLgrQ8rzJq3RfbvWRMz9BurIJYGWCnkkINr+lURV0Od1
+IzilZlLuCWCh+WS8w4sJuoziF71Ick3Pf0DCpPIte6PMqBWerrbmXlRfYZgP+vrH
+JZ6ZHUEkOVawuY91QRW5HKsM/8RDwgLP7zvXtt7BaVey0XW9pRVQM0fzYzW9wufc
+B9DMQeampdXv2R3iXVDQRo86zCRo+7UrqEpBGNXBNhWozucw5eidJo28U+76fWng
+7rpDrOPSOUWcg/IfWDrm+zrPyjX/9sFuyjP2w+/dsxmerYk4yXYOQaVHJYaBgAO4
+O11WsjhZZ0bvYgxqJjHs9WGfg7ZfuobzIK2Pl1ZwU0lAcePwuHTBTBFlI6wUxmhG
+KM2V8vZUMopxUSw3AE4lWZV756ST8Tc9cVVllBg9eRGHdFN2NKullRzTvLMuUwLc
+IGkL6h7VrPmQUhgjyHO4mWgE0or4bm7pHRjP+1D+dxTlr/OZUAiCMgxaBo749Mas
+zgvDqcxJOtH/9J3dUeTzN8C1RoKPQPv1znmJ3OgpOKs0cNz1qNIQGQkYasl4awq3
+nPz7QUqcKeZgy/6KIInOPJ8ys2+R54hFhOj/NUBBZID8EX+IRgQQEQIABgUCUw4x
+bwAKCRA7Ok8Kx55balZeAJ99U3htpjHcxLxLS9lkGT2+YiBIdgCbBLVVwOBCU7qt
+mdHezw/Xp2oxxNKIRgQQEQgABgUCUxNB9AAKCRCgJ0huCLbaUCjLAJ9Iht8ctGWu
+SiDFxodDIHmyJ2z8wACbBDGyGhDA5TVJphdJm9Qo1LYKgc2JBBwEEAEKAAYFAlMT
+McUACgkQsAucyC163ywE0CAAtVzeWwkCwf5ISyWjXosLnbxohXvmq7uh6bdTVoxW
+d1V882pi1UAxU/UZFhb7NSvLaz/hr6+WK0wldl27BF74d6j5rE/3r47KVeOEUuAw
+g/J/tLEfzhWtficG13qnLWyf/iTyP6fCIaFRNHL5PK6Br8xZHS0YF9zRHaCutwTm
+MHV5KinKktgA6Su7YmGwB3f1lirXxUa+RiGAkvg8tIs8Hn+V2x+FDD22QgW4FDh4
+CFYrzz8NsUiIkYawlIHQdnCkQqiFii7MZOG+EsJ86P0lfYbfJfxEY+4nI737YfXH
+SCiWjDTiZG0Hkvrx3qbt0L+Ixydn3oGkrfP+ZngPBj6n7QkALAUFBA34+cylobOD
+jb1nKGM32iqPx50GpaS3KH3WmqqXaR2+6SbUUdZvmwac6vQvtRRfEhVtWB9irXUS
+wn218Ki2EgprAHwrsvLeMJYoR1U9v1UvSrFj5qtiagJYecxDhsM6ozHmcB2PKdE1
+VkIv2vPRzVsfuWeEFnPOSOODsV1Zu00AfceotvAEZd+VdXNkJ3MfWEy7VT52FnG7
+FntzqDXxGkYZLxK6zn0Qh6udvRz65Q3G0nd+USkAmhEBMTr1/La1LfMAibyUyiyL
+0bTRHkjXQc8SpibduFzpcWyrMELVqt1PXgaqtujcjVoHwo00NgJIedBosHVuGBXW
+PpUQx2DkTnIUn5Qkncf8SpgCCGFs6Z3qwcqrc6Pb1Sg6XQ6GpMTYMZO0yaLdSSrS
+vl6wdiJAzvlP1haafInnNFAo6qgaGNgdiSr1r+SpYycFHORCdqimLax5ggOxh1Y+
+V5uZxDDvOSJQUNKO8bDfREke6gIsNRCj7hRutz9F2K566pu5Tn9UAiv1ZfqYxBub
++mkjkctRw61DlqHepJkY1KQTLBphVM9CAADzWPKGRVZtjeYyLNPBap2GbciBQgzr
+/2UCCWAGraxpniCizgkFRPRFaOSp4p0p8DozR3/7xftLPXNgudUbRjxNlRX+uPj4
+0jSEJT1Yrc1/hKgOWvmP13WTbT9/8F2tT+Gd8DTLHa2pXMePOX/dPmF7g7IiEUo9
+Pmci3gFMd0MU1+tgjGZlFs771MZUBnq9rrsX6K5PcikE+UV354mTuF/GdL5Qvwbn
+7DQ0Z88FQ4jTatPucEghTLnO9ahB+5ZlE9ri5hWTKRMZNkX0KlCcgcNpPTJ9Ya3e
+vWUnuhPHmxq7jD0Fc8VLjiKMWSMMiqTrxdgit41ocZinCH54JKtYb41lsH55rx9q
+8crmWdsIKC/Dru7h0MXQW0iU92eMOxiCbXuwNqnzYxWkhjjydhUXmOcufgzfh9Ry
+S8zBC/rw5AkhmuMEZK9Ksskt7SvDPqdd0209JrHt+SA8G4kCHAQQAQIABgUCUxDx
++gAKCRC9U3Jvvaau2NoJEACzaTZ8rR1F8+pIy+JdUfQxmZ80CI2CMCjUt+WieiRz
+3ZH2sgKqwx4T0c53n8938cwXmwdh5xG17sGWDS8VpXUQ3eq8nHPbc12zJFOWM+Ix
+fUIT6zapz18m9x4BjfP78QovU5OyqeE0KtvfwXNvp0OjdoEs70WCaGdmAAcpOd1N
+Einz71DOtDcvRdS7A6jqUwfohemu2iPGj7gvUoykb5gg3Nql4K1zQg+Ymo9RH8Bu
+MA+ebOvwaRaozi9q1Gjg5erXsN+H9TivoMwRiAHdlfeETuGWTFJl0EhtXMHiUjpz
+fA6UsR8LgRMehar8rcsWRY2x8oH6L7Wf2JLc+XnZhAe6wKij5BlbJrJBZc7FcoMJ
+KqxGlgLnMDXL5nmHfaIxiJUU6qe9DSRvGyMB1rr9xxeHp3s9DVR8G6Zaub6ufa7k
+8lfCKbJBru5UD/FrWPMNztiG8fgRg9krmU41ZgvhT5ksZmH5rcFgK7IOowiN9Bxg
+tAclbURX6uNc8CYmWVkR1f+zFS2ChPEebyK+R/VZm0WH3Rz6tacWUtzxr1GryLUU
+wTmxGnyXflD9ySAkjEO60NdwUpofeX9qMzza/sJPpxZsGmy3PHByS/AhK7wnPSlH
+52o9BTVqwY9b6B+oOnswjccgoNyQmtQu84CnGlUKG0y40ho3F1DCHH/l4jrYaxsY
+J4kCHAQQAQIABgUCUxHKygAKCRDABX5xTWlPsl7XEADlAVK6EiOs88azKcH6h/uY
+luxi8F97MOEcyjKrfliRxc5Wt2Ry417ngVelhrIzZPoUi4iT8znazQ+GQWBHS1SY
+51AEqPN0wrbLpMnhM7cHOZ+Yh8za/G8mIpXCInrsFoDsGTm6jBuwhsmD80HJ8ctq
+7DTxrxEfklPuKmQ0ZgbH4wwEmTeU8pzzLlBe9yiDOYVXscG6xffPp6Jml+H2buAb
+B7zZKD/yXuNKgs7AonMLrA6d297wslMAZd9lZ67jmLvWLUhd7LGaA2xVNO2+5yNx
+gMXrdL0wY6NdUY+yy/48b8izD4Hxc0+7wfnZgeND2tgg3av+hbX0sRbIoP7uZgrl
+JKuYuHpgmzQ0Y4eoMklWiWl1o7A8d/vVPuGSOztXUhlQF4nKfEAyn9pFyu4UXjfu
+NueBTQl8Hqii/wN2nMk9vZz2xFN2bnsqvIhjnMA2yoQl5bs576yj8Rbji9eK4ZUg
+WMAkuOkB675DX5rYrXUnDNo3aBS96NQG4CbG/jaM5i0a+ClVg9tVboGksBJZRzUs
+lUQxo8AXS+h74iipJrokigsrq20jO2t/WdxRdxduXu5IOs+hB6ae81JjjHjTFNDu
+uteDnnLNG1dBfebw/RkH3cjp+lsvnAks/mINStMoPEH7/Obvzuku32UvAxglkY47
+QSCJfS4QpkD4G/NUvNFhVokCHAQTAQIABgUCUx5jgwAKCRCtltamwB49Z5zGD/9G
+Is/hfe5iQrSP9NFNChQjaeafjprCMfi30glYsaXM3y2rrXZJh7zKAvOhYcZwbWK2
++9meRzuMX2P2iG3WZ7iyaoPALb1WpPlSQef34g3SJRV1UDVKwYpkJSZCsqIX1bhB
+sr4qjY7pN46B7GX7RrGl79qDy/CUzLciJ1bX/BiB4L3+ls4qrrfomO3+r10ngqzT
+MMmn5hjVWE1BDcuViKYwhW0u/HcTulIVkIp3+Vs6nX54d7nG45YHdmBeLPA5fEFv
+Xe3Q3Q0YwK4r/bZwEqlg2GVg5npYIB7SB7MbU1znuHJvyUpTeO0z8lNWjYjKFedb
+YmO/tQSoJ82GQt9HMaENKxKP4Tk8Wr3SV3y177nD8+6jFWJQZ8lqsQ/GxZukFWPV
+0Eo9dRsQx5v+B5h2213hK4YcOhJaiVtBggUodIKiGz8sW89V2L8EATMb3lAJsvPu
+FiQkuQDOhDlbqAj0yQfyBxKmKCHOfAJ2Q3aYBhvFFXho+DBnPjS9r3QfL1z3UYNc
+Y8tCT9Um+MX6h/2iAodpxtu4xqHd2PavOxLsOA0IFKIcSNOp731VaMPdptgCOoCk
+r7JL7PrH+7QwBPQzCr74rQhiTfuDd1vbmgJGm/D/MuPX5+KemVqOiE+o6xotCb6Y
+KqAWu9CqW2m2L8QuD4hNR9NV+StJWmmNaCoOOXZQXIkCHAQTAQIABgUCUx5k3gAK
+CRAObqOOk0fwLFbMEACNkB4OlOW32GFzalq6uf2vmG9H99+/pBiKyGKvc50obLwK
+x4g8RM/dH6zduHUZ/uJJ08Qvx5h53JVYPOdxk7cXvWVnFJXRQNqgRotOLj9r8Hpa
+Rijh4GrTDXeVrNY1rw+Okw7v2iyNwWQDVOkAzrg/fZ5cZRp9e2Ti0cN4COcGJVQJ
+lHYfa13GuiSUSdc2OisYiQZWXdT8SnjHLb5cL6GRgmDDhOC/FISiu1L+LFIsyXoZ
+9pzFY/43sGTmZJjFnudoxEQHuXmbQZ4Z6o0yAncU2bow0QEQQ/949z4GHNcbXduz
+eXBWXO0kA6z4Lu8YLBk9ihrka3kw1Y4VtvIuWQDuLV7DR/k3/YHZzUUvzGH3c8Vn
++DTK5f/dp2TrK63Py+x4/7E62V9uk/VB+TVy0E6vic0Tk3+KMGUHsVWGZiYXYnso
+ZpVw7/2vMmiPxai35RMe/yi8r7pAYrQc6su9o/WMS1Hxhp3VPa/g4S/mBfk8jse3
+tHof6ZTYAG7t3FhxVGXgHRYa0nnmHf9bLtNOHrAJ4M07z1VB5wMkFJ491nf05oVr
+cyBA3swvliwAilskCfJFFy1yttnOlYY1hLVq7fUAoMfjux9BZglXlmCPp5HlaT2t
+rF6VThREOAI8/Es/zrYAgntLuPFLJcYvjqPEChttT8I0H5KlzoSMfHZybsyW04hG
+BBMRAgAGBQJTHmQGAAoJECKBkcFWfiwXbtEAoNyetrXS29ORsTlasGUPwumYgHaa
+AKCv7Ky87jcPLoQHLp5ugFOyMAXKc4kCHAQTAQIABgUCUx5kQwAKCRAo9QGWxDgC
+6wDkEADFhTXNCEedftkHSLl6GxWCGEi1qI418U+cn01hRCtIY0nVjzGYJaxHamtD
+2cepVSDDdIeXj9C4mcy3na0/mME7+H/tLuZiOv5d5rFIIK6gODmE/69LrCGSLJL/
+1ULCQMqQ8IcKDEkZTmStEKJZPvE/lPmfjn1XGf5gC8zbTg59hN6op/bRuQpQHsIi
+LNn7jEW4X65Ygig/HcRK0Xj6iTEjPc0ITMthLPG5XHUjMeRt+syc65Hl+Q18zwsX
+i6bjp/DKLgDUdLvmXdBSxmsDZgZjJtfE5C/C0Yom/VpVesXCWCZqe++GT/K95dSq
+pZbu0DSVKtrSTqglRJf3gPeVwQUFixjj/tynZHiO/7cZq0pazRrX2qM2ZZB1hkhZ
+VkISzBMUFC8YPkbVDKVYisyUJLdUEKdSB18RcX/ZxLUOsYTo3CsUIwoTH6aL4yQB
+C8rB0OkbJeaZbU/3dlHnycAas4ze6hzvEdiYyb2jrg37qbJwg0CPDevsNkLu/Ie/
+6BqqXcLszWS52aNcyLMPTpjvQIC2gV1f450chsiw9yeMUtsgVFXADO6+8zM1io9B
+1dtEjRXvaiI3jD/jqV+g8TV1i411NHw5sW9c/Jx0UuXDa7gmb6+6VvavIHCF0pLL
+FKUCMmoFePtp0dvdqN1Ysv1RBn7GKl4GGImE0dh5T8pPlXc57IhGBBMRAgAGBQJT
+HmRrAAoJEFk2rKVTkFoB0E0Aniydu8kZjiaob6/OT9hYtOkLaQRqAKCD+l2caV7i
+J/SkLCBgY2relojE2YkCGwQQAQIABgUCVGuZsAAKCRAXscp9ZAiVKMxYD/iZPK6P
+qwHxzEuQjquo8f9f0q1RkX4AZa1j5hvXcqAddUa3HpihHDFnW0UDpptlyonryxUE
+imhD9a22/eIsCz4sF8gAgrp9b1gRBJmJMvtRgVHaFn1u02/5IEvRj7JsWgVXzWFU
+yh9zLaiQtcpfvfFzmdZKtZ3hl0TGl8NFMLxUsownR2tx0iuc8r+NpzzKpxQeXlYS
+98DrDLjE3AKVSZcc8DUBTlwhCZLiXEaQjAKXW+Mxfg8C2E4hQIAsqLWhj8PRQEpG
+w9F0Wdrh9w4ePsKKnzsIaprkRve3vzEuDLvmHV+9DQd/sh+C5W1LjL4h+vC0eXhd
+42lIWrfgOhai2rrwgfSNEFnMAsB1zdWcwMgVSP97sSVfyrqMlDJWXuW8v2KR36ws
+zZnqVPsgQk0Uy53mItUnWblgabSb/udVa+ZI6NeOv1bMGMgKaFqXCn6aHD1X1/E3
+0XtCy2dE6reTAU0zNaRc9ZJOLvxJj8ymP+pUqzkvxLMWAuqpCKsM6YNFlCFkzdfO
+LHxhqGp68jKPUfuG7z6yRkgDZF84k55SUK7td8lHmJpbeiL1+N8Sm9CujQ+TEAbA
+ZFAQjonwnzXWxzI4N+1TWM8BbhLmFpG814JNxyswYdmps6pdKCWHi8zC60dYZ6Mw
+IQZfNWpkeLh7W44NuSJ7pIXuSfEaFCKXX+RwtIpEYXZpZCBOb3J0aCAoT3hmb3Jk
+IENvbXBTb2MpIChJIGRvbid0IHVzZSB0aGlzIGFkZHJlc3MgbXVjaCwgYW5kIGl0
+IHJvdXRlcyB0byB0aGUgc2FtZSBtYWlsYm94IGFzIG15IG1haW4gdXNlciBJRC4p
+IDxub3J0aEBveC5jb21wc29jLm5ldD6JAj0EEwEIACcFAlMOLj4CGwMFCQlmAYAF
+CwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ+bj6w7SBJVMTXw/+PqnnuxB7vBpk
+/rSeunEmZ+qhswnAqjazDLe7gBAPZXKYe6fIdBu0cZpPc1dqlKUY7s7OAUB/egF6
+nHZI7Ise3fq1PJgh1ZKXHtJv5tDdIHZ7H68H+1f+JxOBDDAIdhbr2sogoBRkeYxv
+qE4H4oZt2Ntp474ThU4RHUjHaIVM8uOo9f2xvy0hCUGUHPs9lM8l293LwAtwTMMq
+unUzwXQTnXcZv+4AffBiR438u1FFizRKxiVsFZanAWdzW4Es5XSpeSZYsqofR63i
+lYukjYYRUYjqtAOqCh34hHdUCp2edENG0alSjHded+T1H8WtFARTihyb7Dd5oMP1
+wA6pIzhhKXl9eSMXqpmFvPbrFiD0dlOes/guY6smy+z0S3BldUe+vqF18hhIHpIC
+NPrPc354Vg0hgnsx3oHKYcD7uMAS/vJrOUfJV+xFSjySHadvX9U10Blv9l18su2b
+AT7s7go04eEleKXJwaPVaYZUVaWFmd9WYay0GoNg8aKjke7Fj8cvPhmhn5gHlbj6
+9BBot7eNcHLEAYvhjiO5kBBYRn0skEPRvgxapwddG+9VkpYWi34IX7kC2c1yaQAu
+GQCio641oribB9PDwU2gmvr5L70XexkxfT6Jh8L3Qur0gcnKKDRuqq9LHAAen131
+DpL+Bv2qmYuUb21cy1JYVBDpbn7j2AqIRgQQEQIABgUCUw4xbwAKCRA7Ok8Kx55b
+amtlAKC3RJdB/Csdw+gnbImjWoVGs+E8yQCgpeMDerQA72Py4Si6qgpDEWFhOhCI
+RgQQEQgABgUCUxNB9AAKCRCgJ0huCLbaUJXOAJ4x85jehtQViJV2WmteRuPQm9aK
+6QCeLA4NmWELWo1X+Yeyf5iVPH3jp+6JBBwEEAEKAAYFAlMTMcUACgkQsAucyC16
+3yw85B//S1KwKCIKAlpqRP4x/815btZlDMFr1ve4VkFoSiCAiQTtreYlKqt6Ia8s
+oApHgvSFmCFo1S0q221ohIlW2At4BVKUVWqkwmEzGP+uImI8JzjfRWkfZukyXwYt
+AbDaaKn6nH1mP8gIsaV3Y5jM7mcfcLZVpiXE/+UVvudGjixonN37BsgHV+9lp/AF
+IMs0rH+Yl0tRFpYfAWCBwP3ZVOzyPbtN1gVKc3LXMhPOBfNG+7knFzI1b0eor/E+
+0vPXZ4pZEknRtulli/95ME0WkzFbvz0fx8AVAYWkJytqDF/gIsjiCq5FNAYWA/7C
+T05Np/3g5IbTSceH+bywHA/BH1PGf+zb8edIRhzKi7GbtcHm0kHSiRTnGEhDqy5F
+RDy8WOI43KMw1gDV2EhS67Ns4oMa2g10RZizTDFIhQeiayxM4irYzz0MmWvr4SMC
++jU+H140MxzD+VeZCbpPTBgFoMAZV5RO4bG6BiPFZ4bKGkXaKteWcR2Z6xkyLrcm
+rV1OQw6tKDslqUJnIgbr4eQy8PmgKZ+WZi7i30YZU62nOzzK8FRgBcxULbF4QF3L
+/T282rBM6YA58pdbBTQZ8RQm5gsl3zhtIC5LVPMYHAtmm9dQpZgrrrRhJYzJOCte
+SJuIh11vbK0b6THLX3jzybmgeetcBzI01gXSAhnczQwJnEjvxRA84blk1zAFbZyI
+j5h9+XGnCLGmupYX5yKoJ+IQyvPJn6yO1cc1gMT30jCK4yRpGcq9spDETxB9k/oC
+tYXu4db0LvqhIsiVYhBzha5x44WxwOysnMCVcSWSo9Xr4HkycbxstwvZVraT9oxy
+9AIjJJ6ZS8ntCNGUofxeSPdojyz6B+LXXrgOPxh5yHVH6vDfFQzgDTISTPO4KNWB
+vOMw2IXhcSNKZzmk8UQBOHTCQ/Pyu52Sb9MDP8d8nPCfVxZjiO+2PpuJnraL+zge
+BlIOm1mLMZelYJXyKF7bkE8yeaBtmCR6bgqpRsIAuw91wxTXG0/B3oiiVW3WXi9O
+611ycF4YvjlB5boAC9t7cxS2MXFFE75Zh8az1LuEkgq+/pJBCf4v+IXxrC3kxxLm
+OPgu1iPVuDigviWbftdAeLQ9bsQSQv0jR+/jGQzyQllxHq5ar4zKUBhxRlke4jHG
+KUOSyYznXQwCGlCgvKWLaY2WMjrPuh5vAWbDKRvORlto9Jgr+pcD7H8Hs1380eE0
+elBcYtlHO0mMSX66ycnjhNRLKzMUHZMw+UO2mhUV0+9fQmfGR5u4996+usiu0kL2
+9x207gBN7RKDZ0/XVuUzXaHuS8rY0fhuSj2C1WIUcCy8sTvR9tWznsCG58GsP99f
+ylrvBtKg3vTLjsyBoZFsfDzVmjvVuIkCHAQQAQIABgUCUxDx+gAKCRC9U3Jvvaau
+2H8PD/4+g4mVKclHKIcrjjKvmB4Y7iqOcNeI/Nn5HB8p5Vz19AekYDWBbJX+KxPY
+x7puto5fNASl7LMAFbNt2PVmNJ2wBO3Duda0weHooIiEKm8aLGNWw2BjQYkwTJKn
+rO7E0I1FkXxOByZQdAMshILthfRUZ+jJ2uNyHgCgU28TNoPSUXgpfA5e5KnQF3LF
+0YuFFHSmOFsCAmMO5w/VbVwZxvsj/0CMW4mrIBjBvcR7zEhDI/cefhzXcU0JC6lO
+auyca7NuYs2ytqWqB83wNXQ0zBZI8X+lB3mstKn1kdC6ajRdM4VPn29Hk4bxqiRW
+9IjL+pmnm6BWiTJV3G3givp8tsbtI77lrLfE/RUinEO16QJCs0oUcgY21n0aFaWo
+3c8VA7ThrAvINiwHwiS/5C5FfpfIzUBcOJXMaqmRdvQJ6Urxj6R/P92pj4dZRYg4
+iJFl7BJ8VeG2ecHaE/d5VB9r52SRCtCAckeLDUmD69xF4k2kYpwqf9FgwP5N6D+9
+zZkL8eqotrIoEfrc4d5Ja3P59Go3Tw6P715yISyTrN+qvHSCnHw+ciYEDN6cfVeo
+mi93qU5202ZYIGDFqWzYoY9AO7rk2CIYkul14jeq5Nm+8EZjtghg+1ADqS00ojoq
+LfxIMmNKDoQx+Mb2PRUiJYbA6MzsX5JCDk7+N5gR1zbrqqg1gYkCHAQQAQIABgUC
+UxHKygAKCRDABX5xTWlPsoY3D/9sDReRlVGBiZ6FQkhRVjv5Vv16mev09oRHinK1
+HDK6gdfOO9UWvsVNoi7qTillY7dsp4bAnFvuu0/FG58cD0LDqJ4gzFO6ZRqlUtPV
+T145SatUYuhXv1x/+pAK7mIoVndMvplcEjP+mJl2R2G/pGVDdJRJ+AS8MGLaO+SR
+5ITUwvDllg2rr7HTnxwvT4mMzKozFWlM09cFMU1LYysoh7YJlwMMcyEr7Pc7D+G8
+r6KSQJA2PNVceCICiEvNOd+BsBQuEuAQ3qnBfQ2Hr6GyTtkGKbu96b8CjV+U2chf
+BFe9l2ulVhtN2X+RwLVuYHFBipg9oOhLZ2cHjTSPV96+Oiad+UYplTufQphumjHa
+1FeH6M1lgB7cANxBdGbY8ZFc0wtbYkCFgsUjSFlYS4AbVcTrdlQvEK36WsQOP1uV
+s/pbsCDgH+dKtRAPfUzSre8gslyj9oGuyqnTsIyCpavSbL09UPPBxQEUsAdlvOCs
+p8KpXT4/4DRcJvvMVeBtYHHrEyJ1oIdWJd58m4Rls71Cuc6OCJQYkLJqWkbFtegA
+rqoVYEXPjXCP0zBkGblsZKK5o5r9m6tDDbzqamSg0AfQgDhbvWGtjPXLj40VB9cI
+J8ntBYyuFAO64llK1qWS8BlCSismWx7EcVpXIr3umCPGI/aa4/S9hlfrFqOGmZy+
+1+P1sYkCHAQTAQIABgUCUx5jhQAKCRCtltamwB49Z/KND/4kU2frZUkl2GXF/DO5
+wj8wk+9nM8zkhqC6BMO8quJviNW0Bhl4OY4jwVjiasYwcPppDyZWW9WAAprECCI7
+t89mbvRC/B6KIl9n5w6jCgg/jAITZ+YajBMmZxdD+m8Bc47nDp3iQubsWMzlvA+O
+OeJWc0Fnlcv49OzpaU3gAD52evZTyrpjRJ2zkggLxJVmpOQVmqHdg/GGicJHVkSo
+YfDyO1IAoAQkzN1OZRBx981xa4hCLIF8DOuBC6Re+SgelVcODYe2dMQnDQuhgfeo
+DTO6Raf2UDdfYcV1tbEZwO5+UV1sPbRhfyu2PYpTYWoceDPu8SxKTRFbSGpX8Zx2
+0PMkLsPYr8+iY4VciLOJ28CKwooU6rGm/LNGTtKRymd7oalHiM4DJ//vVEcZ3P5X
+666yTbgZ8n8Ui95KERGSmSQbr/VbsTivUaeL00On2IxL87j+31gjAC/8zG/it/5f
+8MRozyDl2R2k05wPZtg8v48QuarKbLR4fzI5flV9Jqmcyn6THSXmUJftfY+cGHMk
+/SxCtzpL4w/v7T7nnKzD7PuWPVd7KGJ0A70123A5mbw1KvaQfEJotwW8Ym1fBaFv
+21A+iz7KrmGkWq8I8yFpiIuvjTF56eJLp6AM6Xe+K7mxvCJnn806HT1qe8iFRryb
+GeaGoLj1K4vbJnxFoU1wum5JmIkCHAQTAQIABgUCUx5k3wAKCRAObqOOk0fwLNCT
+D/9ivD2rhfPAoQ5KSkaXdAPHug1jdYkZCUyK8XJl7hM1yFKwRDEjpYZOb5IASo2D
+uSvB5oys1lfWaYmM0LgSL2ONhvpdsrK21y90dH5o+DM81hhVSxKQyvXOmg24G8XJ
+rco+y031iDHdsjNfJH5H/OWITTqKuDKmecQs3Z48zTD9Vr3SkmVlWtyptlc19Jzh
+M5FLYIH3Zzo1qmDyFtMW7h+H1RkkgWH+EIQu0oLePEOTkKNcZm8e1+qncgTmcdH0
+LQr9lonWdR1tb0dB00OUa5pmzFaVqmAHYI/GmUOyEIGuiAAb4N5JYTKxEZAxxELk
+aTbVhGmzh89mqt9tuFIwjDzY9vgh50EM+7XQPqk6dwm2RufxU3b/ueEUNQyWij3P
+oJCBZYE7qCsLL8mxk+KLMSmsmglJB77TJm1XE7C43CBpTXMv7MVnjIibVp6KVfsE
+MtL7A/mGISZHWxuEgG8V4CwM9eXU3jnVdg6yXvYu1JN/7+qebNRD5SG9a71nXQU4
+bEsNtYsC+FcF2BhC4JlWME32O7kRueBrG20O7UlbCipPPdAwEAQW4qHPlO7PQic3
+AqUmvp5ovyAxzMwXkkMYDNdo58eh+Srsi0uOFMXP48bBQLcG/b1/PBKXaVNlBEZP
+yxzo8kp7Dh3+gVHsNJ08HcSSf5/ExJg111wTqVI9gREje4hGBBMRAgAGBQJTHmQI
+AAoJECKBkcFWfiwXw18AnAhNT8OumByLV/egAwlovu4x6B9eAKDDUQa3pWjcH1RD
+BQgY56nsRmP3fIkCHAQTAQIABgUCUx5kRAAKCRAo9QGWxDgC669YD/sG/FxpU2rx
+8ajhDWRou7S6VkcOc9LqoNjmgklqCDdVzYpb0MyTeYQB6tkkrCrH0SiVPAiV0582
+U1AS5iujoxBEoeqULIQOCOjtDsUFpUSiWBKN75b4SIQGdUjZRSlW2WpEiznOIew9
+zFoWFnUgu2Oa6mCHEX8RJr5hnq541xmwSahnwoLC7O2ZzZjtsnoS0GC3I2PYW3RZ
+S5Vb2qhGMur23eGMycqxud6PAVL9sHrdtaFpkXdxRTTcxdicHMYca783ZXm+Ikyg
+QTfA850ezt2EeF8DcYT/r3Q0eqTBxgTEaJOUyDoeDAbaZUtSw0dEAcOE5zwfP222
+WYdXTaeGJj6HyZyyW3/BLn9Sp8dzsc0MxIzjSTWihE6D3Kk9FXK+AZEl4nPzah5G
+oIA7QSyEIQsQWOjhcU6Q4yy1ACns+2nlZP2IWsbolIMgfPXCpGT0SW0lF7bGIvRy
+ZnddnvIoKPi5uvto9woq6a+6CD6rF7kdg8j26mjxVcysX0T+Ajb2DWCEAjYFRBvw
+I04HLZT4owpVQLLME0f8GIOuI6fYgGR4nXLb9obrvjU2We3/6ShqvmDyNSH/xJ05
+qIsGemuhisAk7RRrZPMphBwP9BhxvNljjzukIWd6ckkEQe61DixjyYFccD7b4C4z
+ThRfbqtwL69fmUPb/wzs4bfqPwU2Vav6yYhGBBMRAgAGBQJTHmRsAAoJEFk2rKVT
+kFoBeNUAnRR70AEUF099PtlG6DGtgZnq7AJLAKC8dPOV27zhMZc8J+Kqgdo7H+HE
+zYkCHAQQAQIABgUCVGuZsAAKCRAXscp9ZAiVKAktD/4hDcYJoDMQMbq1aApcfl3G
+DDohSdqpquAigGNXZ1DjjVcIe09mnER+20fZOCYMwemzcczqjMj7OB961bKyZG4Z
+DaQ63vBPWIa4Z1l8u0nmQp1bAxl5BYGnFeguAIgcn5bQGN8EG3guEEOqz3ItDG+R
+OX6VUitRjJQcAc/MVYvk3F7flnRt9WlAOlsBMW/xAFaXamlABAH2+IPYfCeZfWEl
+pdDl40xuH/MB5YzsaBqROezakDh9R172SnebFgibeqBGtIwaZ1KvnvKbWPuCZZZ/
+DuyTMkghAKgp7U28mtR2xZ0tMsT5sjXgZTMDocnR3zkgMeDw8NACpYD3Q5GES5Z2
+TImXXzNbiRlmkcZUwSEEhaD2sG2n5o28OHidnUq9LrRjfT7qH1y4ChbTvpF83XU5
+7OtyqXEDav8RORA4gMOKoyLeQf5PEc4QhpSObOKYT+acaJlpc8I7BKgjy/muqO/m
+WkdKRMkNwmlAEPpI161gE2LbRfd4UqtaikVUdQzFuEjt0sOfq2676k/Dm5ubMx1X
+PuF+dS9e6kwPUfLs9bcrIyZHrhHWx0nW7Emg/GVsuMbzaWYSxBWs5PfoMkR/fl/b
+g4INzoGKiWl3W6TAQdgYwlzzlOSy47ETXjsk0eRAIzbwN8E4Sj+FHUqWBAVq9tU1
+GOycWaP+95muxZyQSTWKCbQyRGF2aWQgTm9ydGggKEFTRiBDb21taXR0ZXIgSUQp
+IDxkbm9ydGhAYXBhY2hlLm9yZz6JAj0EEwEIACcFAlVu+0kCGwMFCQlmAYAFCwkI
+BwMFFQoJCAsFFgIDAQACHgECF4AACgkQ+bj6w7SBJVPdNg/8CqkzQThpSx/bWEed
+e6es+DWvVzppNiwwM/y0X24EbObQARGOc60Bqh0GcnGO/oAj8Dr5QozutUmF1ZiE
+RX/BSBTdQvfGDtWj4I4jf7rbusFoqulF8ECAWjiF58xLg657NpVteVxbmRKTtLgD
+H7BRTaCsxgqjt/2jjWf3LhO9QqosDYBZ6i109aSgNfSrQwYHRi0qQA50Yp0tLpIo
+7udcr3GNZZS71MhBSwfsmwP0tEBhI5WcDkgRY0IX1VGpgapO6fwRqB2NOeBI53ap
+4yZq4Rhc2Q+kZS0v2Uqg/42JfKasrKzhkL2PQI+0d7rFatgsI653viobo9Y/3L08
+Jq+u6st0htNLo3XHxKMwvV6CXVBWA6nylOGjLnzA/sRkpkKxhSJ1xktztPrn0x7e
+NtcXSq6tZTW+uHmdjXfLyArlqgIVOxotLpRPjI1JAcYnwkv00KWtVqzpMGKmwyoO
+1QOneHE52xbhx/yfPBK7uZHXXtMb44He3CfZM0Jfh7gZwVu+6k5WZTuEysBBTuNL
+86wxbSBwNRByIxVL64Fi6UsdvbzE7UJmFohygeo9myZRgKLEYjnWellsaoEkgJ1P
+s1RczyOPJbVeU0PQPWWn+pVqqjgQxE6zaRu+JfVuMyHQM3SnmoyuZfciCVrJd4EH
+h+Qrcq4frzvFFmkB7sdx0//Jp7u5Ag0EUw4tWwEQAMOW2F/ARC8Qaco29TnCvZtz
+q6szMgWoMpxd1vfOi+i6EifFAcHDEdyBIa2CW/QMh9zpRQamO82iIOC9wBmcN4iu
+Bi4ZH3wlxAAfuEMSwdsmPVfZQCgODZrlkCGr/4bgHnX5VGFiwlzZUUDemfIzleIo
+d7FzHZ2zIPxUQbMmPriS/cxUry635fZ0Y5YRlgq9AJzif0hNnx7PnZimxVx0hVBA
+OJmDcc4/st3YwKvCqEuKgaJDJNE82WE5a9KldgPtQdykmyxaKMneht9b8St4lZkB
+Sdz90JhSj1GPsDNl88ui+BuIbgGWobAYVW9gY2h/lP95MM1YNtdBAdcyjGe4RhA6
+T+JD5eznikI5EIOyb0zH9CiVDO0CZVH7tuGtJwBVaRSDTtUdNeR4k6xczFjWBmRr
+3n9en+JD/LrYPN5b6P5Cf/SC5YhVD6scaCKdQFOBOClEKxa2dr5eu/7JgsyJCayA
+dZhsHvph0rMVnbSK5DepiRAjJRryXiJvFOD4PbRAyoaA25cSRbjYVN9TLdMhCnBZ
+Nol5z/AxT6ZH2E6CmcvlFfVE6UhvZFfmF7zHTFxvU/eT4kdd9xJZcY1I+y+5bzm3
+LuKIe5W94DpPJ6aebyBX2rr5OXrK3jILjsk+Zof0nxk3SOOKcrLBhs0dtbA8gv7A
+YIW5c9iKjl9X8i3CiSjVABEBAAGJAiUEGAEIAA8FAlMOLVsCGwwFCQlmAYAACgkQ
++bj6w7SBJVNe4BAAxmSonXAhNxohcplTKZpZvzqzU0+92PGIj6D17rJDy18N1DI6
+7bU1XDjIsR5OC/JknK2nuJKimhIymDJZv+b2VLKEZF+LW4HzPTsdEdHMyzW7WssA
+uQGSnHmELagkUnXLk12zbcieugctN8y2H9efuTL3tl9ARkR/Ns4MhVgzP+2XclOW
+V04fa8GLW9dC0MGzZQJvMk2mzs/2vV7/v1ve3IRZqeLDmpkmZSNTpdB3tUmFARKq
+SduvInOfNqPIcRheVz2TwhghRnwkzJHoJ9Bk+rCThU6QLKZv8o4bf6YKPMkY5z+l
+6S9QXf33vNqwIUDn5qxayT8kRz7/GSChJ9twXVVflb5VTTP5FVNUNjDYxCuHBPlC
+UisOlrHjk/jYf8lX3+JFiUMZN+M7wZIakHe4SyRjMEHWUCnC+iObMP0KJ+DoQJK1
+0Hqhah9I+iJZk8n2WkYp4kt6QSwFi+g4QaLQ6byVbBeYA5JPTikQJlpbVgKrKr0C
+LaodHywrloaA6lW+e+WMlx9T2t13s1XQNxM3WnnRYYMh/nEcgtcw7mZRL6h55erS
+NPfXcVvbo0b+iing/HrOtjK4xU0lypGlQlXcfQcMr0RaNAMv4ExgIzQj38jMzNaw
+9a52BMKzZF8059sQF4VfrIVt2eZZyRUa84QI9R3um3tAho1ORUaOtEyOJn8=
+=keWk
+-----END PGP PUBLIC KEY BLOCK-----
+pub   4096R/27B9F635 2015-06-22
+uid                  Dominik Stadler <centic@apache.org>
+sub   4096R/EF9D5EA6 2015-06-22
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBFWIY8gBEACj8cTCDwLduEQpiO2M1qL+/aMtct7IN9l0BIV9bL1oILyRBdi3
+3DHzP07GWLlr0LaRu/uUQuNVKy5ZIF237qn5BJoQnMQuZ2oQPDbaWdg8XkTJJ8pH
+kBQfsV5CmConjBJmV1rPCSbNbwYl+3fstIRybqgIjt9AK1xPxss4BUtbwSRzP4R2
+OblNfJ2WiD2/BLD/cw5GiBIMnH6LYc4tSoEdnZEv07RJUcTXs547wfCGMfOZLjps
+TRLpCQsTnpWV0X7Y7P9m62OUPEs6XIYJptY/Kv7LaEm8A5SSdTOfe0/SusIa2AR0
+ASb9zAwmuPLLNWhPiHKvXeWmxOgr//tpftvtRGlYYkXq6VbvLyhcjRSPiv1Rqx+W
+byvduNzRgJfSXIwfOIuAo8w/aNebZw6v2JDQYsx+P8KIxWO+MEY3XnzRIKEbK5mW
+vxIIhZhzXi+CkAYV3gSvHISDiYmw3/wJBerTO5Fs4cBIqMWfszTXJOYsPhyTF8Kl
+gOawyq7+kpyil0xRAZ9c0Zq+dwrny/q8Jw22MtWxt0gP1Q2bYoLdNhLQ4NzMGAvQ
+2eo0loXwR88cB1LsBHhBfUYnRbw9MXPMaBH0oHdqb+Zm1XvVJMv2xpBM7jt8LxA0
+rWkAg65tv70jTa5NM2eSda2qRMpVCY5VIvCcoEmGvnnZUA4l81um2Y+MdwARAQAB
+tCNEb21pbmlrIFN0YWRsZXIgPGNlbnRpY0BhcGFjaGUub3JnPokCNwQTAQoAIQUC
+VYhjyAIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRDhlnVFJ7n2Na4PD/9H
+GZuGda4QN1IOFc67RSVoLj1fPgKcEiu6zzarzMGChKsdxoo0ZhmyKaAh5/JZn9nh
+YlHDi1zpIjbDLEwEqr6qXjaJz2fw50BGX7yamM7pFvtNglu1KfyDLogYFDIDktaa
+nHtRUgsTXDL116YfoiJlucRqv/7sTCQC2bsuDaS8jmq5Q+9tVELrivxvHfDqnb9f
++yH9HoFW6lQAPyVHVfpB0nDvmWx3twXjatrNiU+Xp+sGsfHtxD2YUjyft0diw1H+
+1U03FJGG344dUS5ZY9L/IBvIaZU+ovMSjpXshlZRZURzlN1FJljB1YkQgHEdjWHz
+9Ur0boQyyMZb3pYc4hINfLChoQoOlENM05LZE1G+x6aug4EGEWnKQsBfVqu4AwgB
+zQkaStHnNrmtIlEWzQtz/CZeiWpC0zXwi4gdiu/Vk+XOZE0YPxjLsFVIpK+m4B/I
+9VmlXodgUkOcmU99EkmXbR6G74OPYphtlRXRnZVcLSlTKfQitZH96/XBHoQ+k+e7
+uODYS9Zyfq5bFzbCmXLieOTQZUAKL9xv5CH9x4aOcCNeSr6JIlIo8UA4QvP9QkBz
+At4H4F2a80TUZtB54MwydKRInKlCdneZRJgEw2aHNuzuc8CeNxBxQ0sXtPRRjs4+
+bKHc89iggbhQCrJBijlV62jrXlVLqDTaNjOkQn20lrkCDQRViGPIARAAnDyvkbv9
+45FwvG4qU2haI3K5DG4KBUgtnuioaK0aF+GrExkIO/kjR574VTcCyTr8PBbYImOx
+YNaxn9QVG9tLlISworLscur79XVcayxkI3OWFzmAkjtlgrGiymTDmIofIXIh6O6H
+NkwOCkfYV2KcTO+UAf5O+DOPi+YH+Wr83GlbxRSqM6XMIXSkva3wPFWXaAmwCi1/
+JeUyEMdLWkEUfNPA53+1cq7SQEMSzdwEfazovOd4MUzQBoIDYbRdio/UBvTw/sQM
+BpKkjrDqa/Z7am0+TjgmyzJVLtfivgKP8/oluwwNa4OJQNNp4kSqmB64I7YXd9dj
+3FjdaVXB6E8BqOxubN9MDBGy59YOkQW6eeYYWH8zRz8BlaynieslPxZjBeEgQOS8
+ow7RRzyALU4BWrD2WBYu8Po9qr26r0NhzwNtSGt8zeB2rK+FMoKIR/EEJUqKgdWR
+e/8ase0Uy70NQPqTwcZRDYaDvdvfK5YafIVODwUu1ojHqkRdPuRH5UpNdaCBk3kU
+0P8yTb8/qTBee3kLvkxspaMH1kgmUSWwsR7vip7Mra/fTCLZJPhJdpuPxHgd3MtO
+CgTNROlubFhHcrhjOkVTWNfoNbi1zaYZI70mzMasA4cqxMCkzhHDt61ChQa0u7Jf
+kIcGBZe11QeTMmQkUoK+Z+/RR185fPtbb6EAEQEAAYkCHwQYAQoACQUCVYhjyAIb
+DAAKCRDhlnVFJ7n2NV6jD/9qaa+oFiMEZ6QPdk0dc9cwTkVth267i05AxGoIu5IG
+nLlxTWfKLudSaOlmlvj/ToOHCGxtqMkiOQ/r2zNOvm5A/SSzoxF5tW33kq9qTXvO
+HC7OAGIlEWqUN38iiooOwX94LqTDQnQhJSAQgvLOnETY7L/G2RwWTNBNAVmSZQlo
+ZHyB+eidQ2K1xPmqs7jygbI2Evgu+fy0HUkHP/pSR18E9Ed4NAn69F8T/FNBu1tx
+Jiiq2L6T4cY34NWJSVTkzNeN1bKihkiw8xli7GsMAx/M13vXHVslmAf+t7Qmf5wU
+EGiSxO/v9KrkJ0J70TxJ8aSuw2WpmeFD/Yvxg5RmAyvOksKd4qhPUDc1S4a1mIYw
+UnpC3ToqTaFhQrC+C4V7aDD2Z2WSe1sUWEWxebTzpx7jO8Ewk6Wrc8GR/EkLEkxy
+wB572tirOBouppxcUK/y2HyRfMMye550Ky8XSXnEf8BBEQCHSE8qRFNewY/ilZse
+VpGw5vPPmG9LUEuFjNS+cjSacaT0/42O6V/31LKuKPmXw6rH1jo0QJbXRorX+9nD
+LeC3Q0DhbExabeoz+Y20AlxvkVhOL6DlTqKPZA5iyBXBvFB/u5Bm//82FKJHiPjj
+sFK2ZjwJ3yfYEsRZQYi45odzWfHA0Ca2NMsdjmRTk/N7AeaknX5KOFIvFqdZndOE
+kg==
+=rPGm
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/build.xml b/build.xml
index 9fa34a8..d7b5482 100644
--- a/build.xml
+++ b/build.xml
@@ -47,8 +47,8 @@
 
     <description>The Apache POI project Ant build.</description>
 
-    <property name="version.id" value="3.12-beta1"/>
-    <property name="version.rel" value="REL_3_12_BETA1"/>
+    <property name="version.id" value="3.13-beta1"/>
+    <property name="version.rel" value="REL_3_13_BETA1"/>
 
     <property environment="env"/>
     <!-- the repository to download jars from -->
@@ -56,7 +56,7 @@
 
     <property name="main.lib" location="lib"/>
     <property name="ooxml.lib" location="ooxml-lib"/>
-	<property name="compile.lib" location="compile-lib"/>
+    <property name="compile.lib" location="compile-lib"/>
     <property name="forrest.home" value="${env.FORREST_HOME}"/>
 
     <!-- compiler options options -->
@@ -82,7 +82,11 @@
     <property name="POI.testdata.path" value="test-data"/>
     <property name="java.awt.headless" value="true"/>
     <property name="additionaljar" value=""/>
-    <property name="http_proxy" value="${env.http_proxy}"/>
+	<condition property="http_proxy" 
+	   value="${env.http_proxy}"
+	   else="">
+		<isset property="env.http_proxy"/>
+	</condition>
 
     <!-- Main: -->
     <property name="main.resource1.dir" value="src/resources/main"/>
@@ -175,8 +179,8 @@
               value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar"/>
 	
     <!-- coverage libs -->
-    <property name="jacoco.zip" location="${main.lib}/jacoco-0.7.2.201409121644.zip"/>
-    <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.2.201409121644/jacoco-0.7.2.201409121644.zip"/>
+    <property name="jacoco.zip" location="${main.lib}/jacoco-0.7.4.201502262128.zip"/>
+    <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.4.201502262128/jacoco-0.7.4.201502262128.zip"/>
     <property name="asm.jar" location="${main.lib}/asm-all-5.0.3.jar"/>
     <property name="asm.url" value="${repository.m2}/maven2/org/ow2/asm/asm-all/5.0.3/asm-all-5.0.3.jar"/>
 	
@@ -194,14 +198,14 @@
     <property name="ooxml.xsds.src.jar" location="${ooxml.lib}/ooxml-schemas-1.1-sources.jar"/>
     <property name="ooxml.xsds.jar" location="${ooxml.lib}/ooxml-schemas-1.1.jar"/>
 
-	<!-- additional schemas are packed into the poi schemas jar, -->
-	<!-- so we don't have to care about a seperate versioning of the original ooxml schemas -->
-	<property name="ooxml.xsds.dc.1" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd"/>
-	<property name="ooxml.xsds.dc.2" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd"/>
-	<property name="ooxml.xsds.dc.3" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd"/>
-	<property name="ooxml.xsds.dsig.1" value="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
-	<property name="ooxml.xsds.dsig.2" value="http://uri.etsi.org/01903/v1.3.2/XAdES.xsd"/>
-	<property name="ooxml.xsds.dsig.3" value="http://uri.etsi.org/01903/v1.4.1/XAdESv141.xsd"/>
+    <!-- additional schemas are packed into the poi schemas jar, -->
+    <!-- so we don't have to care about a seperate versioning of the original ooxml schemas -->
+    <property name="ooxml.xsds.dc.1" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd"/>
+    <property name="ooxml.xsds.dc.2" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd"/>
+    <property name="ooxml.xsds.dc.3" value="http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd"/>
+    <property name="ooxml.xsds.dsig.1" value="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
+    <property name="ooxml.xsds.dsig.2" value="http://uri.etsi.org/01903/v1.3.2/XAdES.xsd"/>
+    <property name="ooxml.xsds.dsig.3" value="http://uri.etsi.org/01903/v1.4.1/XAdESv141.xsd"/>
     <property name="ooxml.xsds.ozip.2" value="OfficeOpenXML-Part2.zip"/>
     <property name="ooxml.xsds.izip.2" value="OpenPackagingConventions-XMLSchema.zip"/>
     <property name="ooxml.xsds.url.2"
@@ -263,17 +267,18 @@
         <pathelement location="${ooxml.xsds.jar}"/>
         <path refid="main.classpath"/>
         <pathelement location="${main.output.dir}"/>
-        <pathelement location="${scratchpad.output.dir}"/>
         <pathelement location="${ooxml.security.jar}"/>
-    	<!-- classes are omitted on test cases outside the xml-dsign area to avoid classpath poisioning -->
+        <!-- classes are omitted on test cases outside the xml-dsign area to avoid classpath poisioning -->
         <!--path refid="ooxml.xmlsec.classpath"/-->
+        <!-- Used only for ExtractorFactory, see #57963 -->
+        <pathelement location="${scratchpad.output.dir}"/>
     </path>
 
     <path id="test.classpath">
         <path refid="main.classpath"/>
         <pathelement location="${main.output.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
-    	<pathelement location="${additionaljar}"/>
+        <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="test.scratchpad.classpath">
@@ -281,7 +286,7 @@
         <pathelement location="${main.output.test.dir}"/>
         <pathelement location="${scratchpad.output.dir}"/>
         <pathelement location="${scratchpad.output.test.dir}"/>
-    	<pathelement location="${additionaljar}"/>
+        <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="test.ooxml.classpath">
@@ -289,14 +294,14 @@
         <pathelement location="${ooxml.output.dir}"/>
         <pathelement location="${ooxml.output.test.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
-    	<pathelement location="${additionaljar}"/>
+        <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="test.integration.classpath">
         <path refid="scratchpad.classpath"/>
         <path refid="ooxml.classpath"/>
         <pathelement location="${main.output.test.dir}"/>
-    	<pathelement location="${ooxml.output.dir}"/>
+        <pathelement location="${ooxml.output.dir}"/>
         <pathelement location="${integration.output.test.dir}"/>
     </path>
 
@@ -331,7 +336,7 @@
         <pathelement location="${excelant.output.dir}"/>
         <pathelement location="${excelant.output.test.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
-    	<pathelement location="${additionaljar}"/>
+        <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="javadoc.classpath">
@@ -360,6 +365,8 @@
     - compile     Compile all files from main, ooxml and scratchpad
     - test        Run all unit tests from main, ooxml and scratchpad
     - jar         Produce jar files
+    - jar-src     Produce source-jar files
+    - assemble    Produce the zipped distribution files
     - site        Generate all documentation (Requires Apache Forrest)
     - dist        Create a distribution (Requires Apache Forrest)
         </echo>
@@ -409,6 +416,7 @@
     	<!-- remove previous versions of third-party jars to prevent them from lingering around, 
     		we often had hard-to-find build/CI-problems because of these! -->
 		<mkdir dir="${main.lib}"/>
+		<mkdir dir="${compile.lib}"/>
 		<delete verbose="true">
 			<fileset dir="${main.lib}">
 	    		<include name="ant-1.8*"/>
@@ -417,9 +425,13 @@
 				<include name="commons-logging-1.1.jar"/>
 				<include name="jacoco-0.6*"/>
 				<include name="jacoco-0.7.1*"/>
+				<include name="jacoco-0.7.2*"/>
+				<include name="jacoco-0.7.3*"/>
 				<include name="log4j-1.2.13*"/>
 				<include name="org.jacoco.*-0.6.*"/>
 				<include name="org.jacoco.*-0.7.1*"/>
+				<include name="org.jacoco.*-0.7.2*"/>
+				<include name="org.jacoco.*-0.7.3*"/>
 				<include name="dom4j*"/>
 				<include name="apache-rat-0.10*"/>
 				<include name="xercesImpl-*.jar"/>
@@ -721,7 +733,7 @@
 			<headfilter lines="16"/>
 			</filterchain>
 		</copy>
-		<copy todir="${scratchpad.src}">
+		<copy todir="${main.src}">
 			<fileset dir="${geometry.output.tmpdir}" includes="**/*.java"/>
 		     <filterchain>
 		         <concatfilter prepend="${geometry.output.tmpdir}/apache-license.txt"/>
@@ -976,7 +988,7 @@
             <xml destfile="${coverage.dir}/coverage.xml"/>
         </jacoco:report>        
         
-        <echo message="Coverage results are available at coverage\index.html, coverage/coverage.xml" />
+        <echo message="Coverage results are available at ${coverage.dir}/index.html, ${coverage.dir}/coverage.xml" />
     </target>
 
     <target name="-test-main-check">
@@ -1280,7 +1292,7 @@
             description="Generates the API documentation">
         <javadoc verbose="false" author="true" destdir="${apidocs.report.dir}"
                  windowtitle="POI API Documentation" use="true" version="true" 
-                 maxmemory="384M" additionalparam="-notimestamp" 
+                 maxmemory="384M" additionalparam="-notimestamp" locale="en_US" 
                  classpathref="javadoc.classpath">
             <packageset dir="${main.src}" defaultexcludes="yes">
                 <include name="org/apache/poi/**"/>
@@ -1440,7 +1452,7 @@
         </jar>
     </target>
 
-    <target name="jar-src" description="Sources for Maven">
+    <target name="jar-src" depends="compile-all, compile-version, -manifest" description="Sources for Maven">
         <jar destfile="${dist.dir}/${jar.name}-${version.id}-sources-${DSTAMP}.jar"
              manifest="build/poi-manifest.mf">
             <fileset dir="${main.src}"/>
@@ -1508,12 +1520,12 @@
         <mkdir dir="${build.maven.javadocs}"/>
         <javadoc verbose="false" author="false" destdir="${build.maven.javadocs}"
                  windowtitle="POI API Documentation" use="false" version="false" 
-                 maxmemory="384M" additionalparam="-notimestamp -quiet"
+                 maxmemory="384M" additionalparam="-notimestamp -quiet" locale="en_US"
                  classpathref="javadoc.classpath">
             <packageset dir="${srcfolder}" defaultexcludes="yes">
                 <include name="org/apache/poi/**"/>
             </packageset>
-            <link href="https://poi.apache.org/apidocs" packagelistLoc="build/tmp/site/build/site/apidocs"/>
+            <link offline="true" href="https://poi.apache.org/apidocs" packagelistLoc="build/tmp/site/build/site/apidocs"/>
         </javadoc>
         <jar destfile="${dist.dir}/${jarname}-${version.id}-javadocs-${DSTAMP}.jar"
              manifest="build/poi-manifest.mf">
@@ -1628,6 +1640,14 @@
         <echo>Use ${dist.dir}/multisign.sh to create md5 checksums and GPG signatures</echo>
     </target>
 
+    <target name="osgi" depends="mvn-install">
+       <echo message="Building OSGi bundle via Maven" />
+       <mvn:mvn pom="osgi/pom.xml">
+          <arg value="-Dpoi.version=${version.id}" />
+          <arg value="install" />
+       </mvn:mvn>
+    </target>
+
     <target name="dist" depends="clean, compile-all, test-all, site, jar, release-notes, assemble"
             description="Creates the entire distribution into build/dist, from scratch">
     </target>
@@ -1744,7 +1764,30 @@
 			<sourcePath path="src/java" />
 			<sourcePath path="src/ooxml/java" />
 			<sourcePath path="src/scratchpad/src" />
-		</findbugs>		
+		</findbugs>
+		<findbugs home="${findbugs.home}" output="xml" outputFile="build/findbugs.xml"
+			excludeFilter="src/resources/devtools/findbugs-filters.xml">
+			<fileset dir="${dist.dir}">
+				<include name="poi-${version.id}-*.jar"/>
+				<include name="poi-scratchpad-${version.id}-*.jar"/>
+				<include name="poi-ooxml-${version.id}-*.jar"/>
+				<exclude name="poi-*${version.id}-sources-*.jar"/>
+				<exclude name="poi-*${version.id}-javadocs-*.jar"/>
+			</fileset>
+			<auxClasspath path="${compile.lib}/bcpkix-jdk15on-1.51.jar" />
+			<auxClasspath path="${compile.lib}/bcprov-ext-jdk15on-1.51.jar" />
+			<auxClasspath path="${compile.lib}/slf4j-api-1.7.7.jar" />
+			<auxClasspath path="${compile.lib}/xmlsec-2.0.1.jar" />
+			<auxClasspath path="ooxml-lib/ooxml-schemas-1.1.jar" />
+			<auxClasspath path="ooxml-lib/ooxml-security-1.0.jar" />
+			<auxClasspath path="ooxml-lib/xmlbeans-2.6.0.jar" />
+			<auxClasspath path="lib/commons-codec-1.9.jar" />
+			<auxClasspath path="lib/commons-logging-1.1.3.jar" />
+			<auxClasspath path="lib/junit-4.12.jar" />
+			<sourcePath path="src/java" />
+			<sourcePath path="src/ooxml/java" />
+			<sourcePath path="src/scratchpad/src" />
+		</findbugs>
 	</target>
 
 	<target name="test-scratchpad-download-resources">
diff --git a/doap_POI.rdf b/doap_POI.rdf
index e0123c2..17dee9f 100644
--- a/doap_POI.rdf
+++ b/doap_POI.rdf
@@ -21,20 +21,54 @@
     <category rdf:resource="http://projects.apache.org/category/library" />
     <release>
       <Version>
+        <name>Apache POI 3.12</name>
+        <created>2015-05-11</created>
+        <revision>3.12</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <name>Apache POI 3.11</name>
+        <created>2014-12-21</created>
+        <revision>3.11</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <name>Apache POI 3.10.1</name>
+        <created>2014-08-18</created>
+        <revision>3.10.1</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <name>Apache POI 3.10</name>
+        <created>2014-02-08</created>
+        <revision>3.10</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
         <name>Apache POI 3.9</name>
         <created>2012-12-03</created>
         <revision>3.9</revision>
       </Version>
+    </release>
+    <release>
       <Version>
         <name>Apache POI 3.8</name>
         <created>2012-03-26</created>
         <revision>3.8</revision>
       </Version>
+    </release>
+    <release>
       <Version>
         <name>Apache POI 3.7</name>
         <created>2010-10-29</created>
         <revision>3.7</revision>
       </Version>
+    </release>
+    <release>
       <Version>
         <name>Apache POI 3.6</name>
         <created>2009-12-14</created>
diff --git a/legal/NOTICE b/legal/NOTICE
index e5aa5f5..be2eae7 100644
--- a/legal/NOTICE
+++ b/legal/NOTICE
@@ -1,5 +1,5 @@
 Apache POI
-Copyright 2003-2014 The Apache Software Foundation
+Copyright 2003-2015 The Apache Software Foundation
 
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/osgi/pom.xml b/osgi/pom.xml
new file mode 100644
index 0000000..2849467
--- /dev/null
+++ b/osgi/pom.xml
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>10</version>
+    <relativePath />
+  </parent>
+
+  <groupId>org.apache.poi</groupId>
+  <artifactId>poi-bundle</artifactId>
+  <packaging>bundle</packaging>
+  <name>Apache POI OSGi bundle</name>
+  <description>
+    OSGi bundle that contains Apache POI, and the dependencies.
+  </description>
+  <url>http://poi.apache.org/</url>
+  <version>${poi.version}</version>
+<!--
+  <version>3.12-beta2</version>
+  <version>@VERSION@</version>
+-->
+
+  <properties>
+    <maven.compiler.source>1.6</maven.compiler.source>
+    <maven.compiler.target>1.6</maven.compiler.target>
+    <pax.exam.version>4.4.0</pax.exam.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>poi</artifactId>
+      <version>${poi.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>poi-scratchpad</artifactId>
+      <version>${poi.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>poi-ooxml</artifactId>
+      <version>${poi.version}</version>
+    </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-junit4</artifactId>
+      <version>${pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-container-native</artifactId>
+      <version>${pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>4.6.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-link-assembly</artifactId>
+      <version>${pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.url</groupId>
+      <artifactId>pax-url-aether</artifactId>
+      <version>2.3.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>5.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Activator>
+              org.apache.poi.osgi.Activator
+            </Bundle-Activator>
+            <Embed-Dependency>
+              poi;inline=true,
+              poi-scratchpad;inline=true,
+              poi-ooxml;inline=true,
+              poi-ooxml-schemas,
+              xmlbeans
+            </Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+            <Bundle-DocURL>${project.url}</Bundle-DocURL>
+            <Export-Package>
+              org.apache.poi.*
+            </Export-Package>
+            <Import-Package>
+              !org.junit,
+              *,
+              org.apache.xmlbeans.impl.xpath.saxon;resolution:=optional,
+              org.apache.xmlbeans.impl.xquery.saxon;resolution:=optional,
+              org.bouncycastle.cert;resolution:=optional,
+              org.bouncycastle.cert.ocsp;resolution:=optional,
+              org.bouncycastle.cms.bc;resolution:=optional,
+              org.bouncycastle.cert.jcajce;resolution:=optional,
+              org.bouncycastle.operator;resolution:=optional,
+              org.bouncycastle.operator.bc;resolution:=optional,
+              org.bouncycastle.tsp;resolution:=optional,
+              org.openxmlformats.schemas.officeDocument.x2006.math;resolution:=optional,
+              org.openxmlformats.schemas.schemaLibrary.x2006.main;resolution:=optional,
+              schemasMicrosoftComOfficePowerpoint;resolution:=optional,
+              schemasMicrosoftComOfficeWord;resolution:=optional,
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+         <artifactId>maven-compiler-plugin</artifactId>
+         <version>3.2</version>
+         <configuration>
+            <source>${maven.compiler.source}</source>
+            <target>${maven.compiler.target}</target>
+         </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>java6</id>
+      <activation>
+        <jdk>[1.6,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+              <execution>
+                <phase>pre-integration-test</phase>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <configuration>
+                  <descriptor>test-bundles.xml</descriptor>
+                  <finalName>test</finalName>
+                  <attach>false</attach>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <version>2.10</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>integration-test</goal>
+                  <goal>verify</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <systemPropertyVariables>
+                <org.ops4j.pax.logging.DefaultServiceLog.level>
+                  WARN
+                </org.ops4j.pax.logging.DefaultServiceLog.level>
+              </systemPropertyVariables>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <organization>
+    <name>The Apache Software Founation</name>
+    <url>http://www.apache.org</url>
+  </organization>
+  <scm>
+    <url>http://svn.apache.org/viewvc/poi/trunk/osgi</url>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/poi/trunk/osgi</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/poi/trunk/osgi</developerConnection>
+  </scm>
+</project>
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/osgi/src/main/java/org/apache/poi/osgi/Activator.java
similarity index 74%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to osgi/src/main/java/org/apache/poi/osgi/Activator.java
index 48744ec..2f0212b 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/osgi/src/main/java/org/apache/poi/osgi/Activator.java
@@ -1,22 +1,28 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

-

-       http://www.apache.org/licenses/LICENSE-2.0

-

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

-

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.osgi;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+    public void start(BundleContext context) throws Exception {
+    }
+    public void stop(BundleContext context) throws Exception {
+    }
+}
diff --git a/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java b/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java
new file mode 100644
index 0000000..738d96b
--- /dev/null
+++ b/osgi/src/test/java/org/apache/poi/osgi/TestOSGiBundle.java
@@ -0,0 +1,84 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+import javax.inject.Inject;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Test to ensure that all our main formats can create, write
+ *  and read back in, when running under OSGi
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class TestOSGiBundle {
+
+    private final File TARGET = new File("target");
+
+    @Inject
+    private BundleContext bc;
+
+    @Configuration
+    public Option[] configuration() throws IOException, URISyntaxException {
+        File base = new File(TARGET, "test-bundles");
+        return options(
+                junitBundles(),
+                bundle(new File(base, "poi-bundle.jar").toURI().toURL().toString()));
+    }
+
+    @Test
+    public void testHSSF() throws Exception {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet s = wb.createSheet("OSGi");
+        s.createRow(0).createCell(0).setCellValue("With OSGi");
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        wb.write(baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+        wb = new HSSFWorkbook(bais);
+        assertEquals(1, wb.getNumberOfSheets());
+
+        s = wb.getSheet("OSGi");
+        assertEquals("With OSGi", s.getRow(0).getCell(0).toString());
+    }
+}
diff --git a/osgi/test-bundles.xml b/osgi/test-bundles.xml
new file mode 100644
index 0000000..1150276
--- /dev/null
+++ b/osgi/test-bundles.xml
@@ -0,0 +1,34 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+  <id>bundles</id>
+  <formats>
+    <format>dir</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <dependencySets>
+    <dependencySet>
+      <outputDirectory/>
+      <outputFileNameMapping>${artifact.artifactId}.jar</outputFileNameMapping>
+      <includes>
+        <include>org.apache.poi:poi-bundle</include>
+      </includes>
+    </dependencySet>
+  </dependencySets>
+</assembly>
diff --git a/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java b/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java
index bf6bcd1..8d1a0a9 100644
--- a/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java
+++ b/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java
@@ -93,12 +93,12 @@
             out("   No. of sections: " + sectionCount);
 
             /* Print the list of sections: */
-            List sections = ps.getSections();
+            List<Section> sections = ps.getSections();
             int nr = 0;
-            for (Iterator i = sections.iterator(); i.hasNext();)
+            for (Iterator<Section> i = sections.iterator(); i.hasNext();)
             {
                 /* Print a single section: */
-                Section sec = (Section) i.next();
+                Section sec = i.next();
                 out("   Section " + nr++ + ":");
                 String s = hex(sec.getFormatID().getBytes());
                 s = s.substring(0, s.length() - 1);
diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java
index ff8a0b7..d2141b0 100644
--- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java
+++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/CreateCells.java
@@ -50,5 +50,7 @@
         FileOutputStream fileOut = new FileOutputStream("workbook.xls");
         wb.write(fileOut);
         fileOut.close();
+
+        wb.close();
     }
 }
diff --git a/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java b/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java
index d0ce767..dd1398b 100644
--- a/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java
+++ b/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java
@@ -21,6 +21,8 @@
 

 import org.apache.poi.hssf.usermodel.*;

 import org.apache.poi.ss.usermodel.*;

+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;

 import org.apache.poi.ss.util.CellRangeAddress;

 import org.apache.poi.xssf.usermodel.XSSFWorkbook;

 

@@ -31,10 +33,9 @@
  * Excel Conditional Formatting -- Examples

  *

  * <p>

- *   Based on the code snippets from http://www.contextures.com/xlcondformat03.html

+ *   Partly based on the code snippets from 

+ *   http://www.contextures.com/xlcondformat03.html

  * </p>

- *

- * @author Yegor Kozlov

  */

 public class ConditionalFormats {

 

@@ -46,6 +47,7 @@
 

         sameCell(wb.createSheet("Same Cell"));

         multiCell(wb.createSheet("MultiCell"));

+        overlapping(wb.createSheet("Overlapping"));

         errors(wb.createSheet("Errors"));

         hideDupplicates(wb.createSheet("Hide Dups"));

         formatDuplicates(wb.createSheet("Duplicates"));

@@ -53,6 +55,9 @@
         expiry(wb.createSheet("Expiry"));

         shadeAlt(wb.createSheet("Shade Alt"));

         shadeBands(wb.createSheet("Shade Bands"));

+        iconSets(wb.createSheet("Icon Sets"));

+        

+        // TODO Add colour scales, data bars etc, see bug #58130

 

         // Write the output to a file

         String file = "cf-poi.xls";

@@ -60,7 +65,7 @@
         FileOutputStream out = new FileOutputStream(file);

         wb.write(out);

         out.close();

-

+        System.out.println("Generated: " + file);

     }

 

     /**

@@ -139,6 +144,71 @@
 

         sheet.getRow(2).createCell(4).setCellValue("<== Condition 1: Formula Is =$B2>75   (Blue Fill)");

     }

+    

+    /**

+     * Multiple conditional formatting rules can apply to

+     *  one cell, some combining, some beating others.

+     * Done in order of the rules added to the 

+     *  SheetConditionalFormatting object

+     */

+    static void overlapping(Sheet sheet) {

+        for (int i=0; i<40; i++) {

+            int rn = i+1;

+            Row r = sheet.createRow(i);

+            r.createCell(0).setCellValue("This is row " + rn + " (" + i + ")");

+            String str = "";

+            if (rn%2 == 0) str = str + "even ";

+            if (rn%3 == 0) str = str + "x3 ";

+            if (rn%5 == 0) str = str + "x5 ";

+            if (rn%10 == 0) str = str + "x10 ";

+            if (str.length() == 0) str = "nothing special...";

+            r.createCell(1).setCellValue("It is " + str);

+        }

+        sheet.autoSizeColumn(0);

+        sheet.autoSizeColumn(1);

+        

+        sheet.getRow(1).createCell(3).setCellValue("Even rows are blue");

+        sheet.getRow(2).createCell(3).setCellValue("Multiples of 3 have a grey background");

+        sheet.getRow(4).createCell(3).setCellValue("Multiples of 5 are bold");

+        sheet.getRow(9).createCell(3).setCellValue("Multiples of 10 are red (beats even)");

+        

+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();

+        

+        // Condition 1: Row divides by 10, red (will beat #1)

+        ConditionalFormattingRule rule1 = 

+                sheetCF.createConditionalFormattingRule("MOD(ROW(),10)=0");

+        FontFormatting font1 = rule1.createFontFormatting();

+        font1.setFontColorIndex(IndexedColors.RED.index);

+        

+        // Condition 2: Row is even, blue

+        ConditionalFormattingRule rule2 = 

+                sheetCF.createConditionalFormattingRule("MOD(ROW(),2)=0");

+        FontFormatting font2 = rule2.createFontFormatting();

+        font2.setFontColorIndex(IndexedColors.BLUE.index);

+        

+        // Condition 3: Row divides by 5, bold

+        ConditionalFormattingRule rule3 = 

+                sheetCF.createConditionalFormattingRule("MOD(ROW(),5)=0");

+        FontFormatting font3 = rule3.createFontFormatting();

+        font3.setFontStyle(false, true);

+        

+        // Condition 4: Row divides by 3, grey background

+        ConditionalFormattingRule rule4 = 

+                sheetCF.createConditionalFormattingRule("MOD(ROW(),3)=0");

+        PatternFormatting fill4 = rule4.createPatternFormatting();

+        fill4.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index);

+        fill4.setFillPattern(PatternFormatting.SOLID_FOREGROUND);

+        

+        // Apply

+        CellRangeAddress[] regions = {

+                CellRangeAddress.valueOf("A1:F41")

+        };

+

+        sheetCF.addConditionalFormatting(regions, rule1);

+        sheetCF.addConditionalFormatting(regions, rule2);

+        sheetCF.addConditionalFormatting(regions, rule3);

+        sheetCF.addConditionalFormatting(regions, rule4);

+    }

 

     /**

      *  Use Excel conditional formatting to check for errors,

@@ -346,4 +416,64 @@
         sheet.createRow(0).createCell(1).setCellValue("Shade Bands of Rows");

         sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is  =MOD(ROW(),6)<2   (Light Grey Fill)");

     }

+    

+    /**

+     * Icon Sets / Multi-States allow you to have icons shown which vary

+     *  based on the values, eg Red traffic light / Yellow traffic light /

+     *  Green traffic light

+     */

+    static void iconSets(Sheet sheet) {

+        sheet.createRow(0).createCell(0).setCellValue("Icon Sets");

+        Row r = sheet.createRow(1);

+        r.createCell(0).setCellValue("Reds");

+        r.createCell(1).setCellValue(0);

+        r.createCell(2).setCellValue(0);

+        r.createCell(3).setCellValue(0);

+        r = sheet.createRow(2);

+        r.createCell(0).setCellValue("Yellows");

+        r.createCell(1).setCellValue(5);

+        r.createCell(2).setCellValue(5);

+        r.createCell(3).setCellValue(5);

+        r = sheet.createRow(3);

+        r.createCell(0).setCellValue("Greens");

+        r.createCell(1).setCellValue(10);

+        r.createCell(2).setCellValue(10);

+        r.createCell(3).setCellValue(10);

+                

+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();

+        

+        CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") };

+        ConditionalFormattingRule rule1 =

+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_TRAFFIC_LIGHTS);

+        IconMultiStateFormatting im1 = rule1.getMultiStateFormatting();

+        im1.getThresholds()[0].setRangeType(RangeType.MIN);

+        im1.getThresholds()[1].setRangeType(RangeType.PERCENT);

+        im1.getThresholds()[1].setValue(33d);

+        im1.getThresholds()[2].setRangeType(RangeType.MAX);

+        sheetCF.addConditionalFormatting(regions, rule1);

+        

+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C1:C4") };

+        ConditionalFormattingRule rule2 =

+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_FLAGS);

+        IconMultiStateFormatting im2 = rule1.getMultiStateFormatting();

+        im2.getThresholds()[0].setRangeType(RangeType.PERCENT);

+        im2.getThresholds()[0].setValue(0d);

+        im2.getThresholds()[1].setRangeType(RangeType.PERCENT);

+        im2.getThresholds()[1].setValue(33d);

+        im2.getThresholds()[2].setRangeType(RangeType.PERCENT);

+        im2.getThresholds()[2].setValue(67d);

+        sheetCF.addConditionalFormatting(regions, rule2);

+        

+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D1:D4") };

+        ConditionalFormattingRule rule3 =

+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_SYMBOLS_CIRCLE);

+        IconMultiStateFormatting im3 = rule1.getMultiStateFormatting();

+        im3.setIconOnly(true);

+        im3.getThresholds()[0].setRangeType(RangeType.MIN);

+        im3.getThresholds()[1].setRangeType(RangeType.NUMBER);

+        im3.getThresholds()[1].setValue(3d);

+        im3.getThresholds()[2].setRangeType(RangeType.NUMBER);

+        im3.getThresholds()[2].setValue(7d);

+        sheetCF.addConditionalFormatting(regions, rule3);

+    }

 }

diff --git a/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java b/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java
index b5480cf..bcfb5df 100644
--- a/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java
+++ b/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java
@@ -289,7 +289,7 @@
     private void fontStyle(CellStyle style) {
         Font font = wb.getFontAt(style.getFontIndex());
 
-        if (font.getBoldweight() >= HSSFFont.BOLDWEIGHT_NORMAL)
+        if (font.getBoldweight() >= HSSFFont.BOLDWEIGHT_BOLD)
             out.format("  font-weight: bold;%n");
         if (font.getItalic())
             out.format("  font-style: italic;%n");
@@ -309,8 +309,12 @@
             style = wb.getCellStyleAt((short) 0);
         StringBuilder sb = new StringBuilder();
         Formatter fmt = new Formatter(sb);
-        fmt.format("style_%02x", style.getIndex());
-        return fmt.toString();
+        try {
+            fmt.format("style_%02x", style.getIndex());
+            return fmt.toString();
+        } finally {
+            fmt.close();
+        }
     }
 
     private <K> void styleOut(String attr, K key, Map<K, String> mapping) {
diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java
index 6ed7608..aa96056 100644
--- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java
+++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/AligningCells.java
@@ -114,16 +114,17 @@
 
         // Make the selection
         CTRowImpl ctRow = (CTRowImpl) row.getCTRow();
-        List spanList = new ArrayList();
 
         // Add object with format start_coll:end_coll. For example 1:3 will span from
         // cell 1 to cell 3, where the column index starts with 0
         //
         // You can add multiple spans for one row
         Object span = start_column + ":" + end_column;
+
+        List<Object> spanList = new ArrayList<Object>();
         spanList.add(span);
 
         //add spns to the row
         ctRow.setSpans(spanList);
     }
-} 
\ No newline at end of file
+}
diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java
index 00c5342..d992815 100644
--- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java
+++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java
@@ -23,6 +23,7 @@
 import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
+import org.apache.poi.openxml4j.opc.internal.ZipHelper;
 import org.apache.poi.ss.usermodel.DateUtil;
 import org.apache.poi.ss.usermodel.IndexedColors;
 import org.apache.poi.ss.util.CellReference;
@@ -165,27 +166,31 @@
      * @param out the stream to write the result to
      */
 	private static void substitute(File zipfile, File tmpfile, String entry, OutputStream out) throws IOException {
-        ZipFile zip = new ZipFile(zipfile);
+        ZipFile zip = ZipHelper.openZipFile(zipfile);
 
-        ZipOutputStream zos = new ZipOutputStream(out);
+        try {
+			ZipOutputStream zos = new ZipOutputStream(out);
 
-        @SuppressWarnings("unchecked")
-        Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) zip.entries();
-        while (en.hasMoreElements()) {
-            ZipEntry ze = en.nextElement();
-            if(!ze.getName().equals(entry)){
-                zos.putNextEntry(new ZipEntry(ze.getName()));
-                InputStream is = zip.getInputStream(ze);
-                copyStream(is, zos);
-                is.close();
+			@SuppressWarnings("unchecked")
+			Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) zip.entries();
+			while (en.hasMoreElements()) {
+				ZipEntry ze = en.nextElement();
+				if(!ze.getName().equals(entry)){
+					zos.putNextEntry(new ZipEntry(ze.getName()));
+					InputStream is = zip.getInputStream(ze);
+					copyStream(is, zos);
+					is.close();
+                }
             }
+            zos.putNextEntry(new ZipEntry(entry));
+            InputStream is = new FileInputStream(tmpfile);
+            copyStream(is, zos);
+            is.close();
+    
+            zos.close();
+        } finally {
+        	zip.close();
         }
-        zos.putNextEntry(new ZipEntry(entry));
-        InputStream is = new FileInputStream(tmpfile);
-        copyStream(is, zos);
-        is.close();
-
-        zos.close();
     }
 
     private static void copyStream(InputStream in, OutputStream out) throws IOException {
diff --git a/src/integrationtest/build.xml b/src/integrationtest/build.xml
new file mode 100644
index 0000000..795788e
--- /dev/null
+++ b/src/integrationtest/build.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project name="POI Testbuild" default="run" basedir=".">
+
+    <description>Test-Ant file which verifies that the Apache POI distribution build sources can be compiled successfully.
+	
+	Before running this, you should execute the "assemble" target in the main build.xml to have the packaged files
+	created correctly.
+
+    </description>
+    
+    <property name="dist" value="../../build/dist"/>
+    <property name="build" value="../../build/distsourcebuild"/>
+    
+    <target name="init" depends="">
+    </target>
+    
+    <target name="run" depends="init,runSourceBuild,runCompileTest"/>
+	
+    <target name="runSourceBuild" depends="init">
+        <!-- clean out old stuff in build-dir -->
+        <delete dir="${build}"/>
+        <mkdir dir="${build}"/>
+
+        <!-- select latest built source zip -->
+        <pathconvert property="srcpackage">
+            <last>
+                <sort>
+                    <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/>
+                    <resources>
+                        <fileset dir="${dist}">
+                            <include name="poi-src-*.zip" />
+                        </fileset>
+                    </resources>
+                </sort>
+            </last>
+        </pathconvert>
+
+        <echo message="Found source package at ${srcpackage}"/>
+        <unzip src="${srcpackage}" dest="${build}" failOnEmptyArchive="true"/>
+
+        <!-- look for name of sub-dir, do this dynamically as it changes with every (beta|rc)-release -->
+        <pathconvert property="dirversion">
+            <dirset dir="${build}">
+                <include name="*" />
+            </dirset>
+        </pathconvert>
+
+        <!-- finally call Ant on the extracted source to check if we can build the packages -->
+        <echo message="Building in temporary dir ${dirversion}/"/>
+        <ant dir="${dirversion}" target="jar" inheritAll="false" inheritRefs="false" useNativeBasedir="true"/>
+    </target>
+
+    <target name="runCompileTest" depends="init" description="Verify that we can compile most examples without including excelant or scratchpad jars">
+        <!-- clean out old stuff in build-dir -->
+        <delete dir="${build}"/>
+        <mkdir dir="${build}"/>
+		
+        <!-- select latest built jar files without scratchpad.jar -->
+        <pathconvert property="jarpackage">
+			<sort>
+				<resources>
+					<fileset dir="${dist}">
+						<include name="poi-3.*.jar" />
+						<include name="poi-ooxml-3.*.jar" />
+						<include name="poi-ooxml-schemas-3.*.jar" />
+						<exclude name="*-javadocs-*" />
+						<exclude name="*-sources-*" />
+					</fileset>
+				</resources>
+			</sort>
+        </pathconvert>
+
+        <echo message="Found jar packages at ${jarpackage}"/>
+
+		<path id="libs">
+			<fileset dir="../../lib">
+				<include name="junit*.jar" />
+			</fileset>
+			<fileset dir="../../ooxml-lib">
+				<include name="ooxml-schemas-*.jar" />
+				<include name="xmlbeans-*.jar" />
+				<exclude name="xmlbeans-2.3.*.jar" />
+			</fileset>
+		</path>
+
+		<echo message="Compiling examples without linking to scratchpad.jar to ensure that only some specific ones require this jar" />
+		<javac srcdir="../examples/src" destdir="${build}"
+			target="1.6"
+            source="1.6"
+            debug="trye"
+            encoding="ASCII"
+            fork="yes"
+            includeantruntime="false"
+			excludes="org/apache/poi/hslf/**,org/apache/poi/hsmf/**,**/EmbeddedObjects.java,**/EmeddedObjects.java,**/Word2Forrest.java"
+			classpath="${jarpackage}"
+			classpathref="libs">
+        </javac>
+		
+        <!-- select latest built jar files with additionally scratchpad.jar -->
+        <pathconvert property="jarpackagescratchpad">
+			<sort>
+				<resources>
+					<fileset dir="${dist}">
+						<include name="poi-3.*.jar" />
+						<include name="poi-ooxml-3.*.jar" />
+						<include name="poi-ooxml-schemas-3.*.jar" />
+						<include name="poi-scratchpad-3.*.jar" />
+						<exclude name="*-javadocs-*" />
+						<exclude name="*-sources-*" />
+					</fileset>
+				</resources>
+			</sort>
+        </pathconvert>
+
+		<echo message="Compiling all examples with the additinal scratchpad.jar" />
+		<javac srcdir="../examples/src" destdir="${build}"
+			target="1.6"
+            source="1.6"
+            debug="trye"
+            encoding="ASCII"
+            fork="yes"
+            includeantruntime="false"
+			classpath="${jarpackagescratchpad}"
+			classpathref="libs">
+        </javac>
+    </target>
+</project>
diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java
index 4608303..85b0580 100644
--- a/src/integrationtest/org/apache/poi/TestAllFiles.java
+++ b/src/integrationtest/org/apache/poi/TestAllFiles.java
@@ -31,6 +31,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.poi.hwpf.OldWordFileFormatException;
 import org.apache.poi.stress.*;
 import org.apache.tools.ant.DirectoryScanner;
 import org.junit.Test;
@@ -65,83 +66,91 @@
  */
 @RunWith(Parameterized.class)
 public class TestAllFiles {
-	private static final File ROOT_DIR = new File("test-data");
+    private static final File ROOT_DIR = new File("test-data");
 
     // map file extensions to the actual mappers
-	private static final Map<String, FileHandler> HANDLERS = new HashMap<String, FileHandler>();
-	static {
-		// Excel
-		HANDLERS.put(".xls", new HSSFFileHandler());
-		HANDLERS.put(".xlsx", new XSSFFileHandler());
-		HANDLERS.put(".xlsm", new XSSFFileHandler());
-		HANDLERS.put(".xltx", new XSSFFileHandler());
-		HANDLERS.put(".xlsb", new XSSFFileHandler());
-		
-		// Word
-		HANDLERS.put(".doc", new HWPFFileHandler());
-		HANDLERS.put(".docx", new XWPFFileHandler());
-		HANDLERS.put(".dotx", new XWPFFileHandler());
-		HANDLERS.put(".docm", new XWPFFileHandler());
-		HANDLERS.put(".ooxml", new XWPFFileHandler());		// OPCPackage
+    private static final Map<String, FileHandler> HANDLERS = new HashMap<String, FileHandler>();
+    static {
+        // Excel
+        HANDLERS.put(".xls", new HSSFFileHandler());
+        HANDLERS.put(".xlsx", new XSSFFileHandler());
+        HANDLERS.put(".xlsm", new XSSFFileHandler());
+        HANDLERS.put(".xltx", new XSSFFileHandler());
+        HANDLERS.put(".xlsb", new XSSFFileHandler());
 
-		// Powerpoint
-		HANDLERS.put(".ppt", new HSLFFileHandler());
-		HANDLERS.put(".pptx", new XSLFFileHandler());
-		HANDLERS.put(".pptm", new XSLFFileHandler());
-		HANDLERS.put(".ppsm", new XSLFFileHandler());
-		HANDLERS.put(".ppsx", new XSLFFileHandler());
-		HANDLERS.put(".thmx", new XSLFFileHandler());
+        // Word
+        HANDLERS.put(".doc", new HWPFFileHandler());
+        HANDLERS.put(".docx", new XWPFFileHandler());
+        HANDLERS.put(".dotx", new XWPFFileHandler());
+        HANDLERS.put(".docm", new XWPFFileHandler());
+        HANDLERS.put(".ooxml", new XWPFFileHandler());		// OPCPackage
 
-		// Outlook
-		HANDLERS.put(".msg", new HSMFFileHandler());
-		
-		// Publisher
-		HANDLERS.put(".pub", new HPBFFileHandler());
+        // Powerpoint
+        HANDLERS.put(".ppt", new HSLFFileHandler());
+        HANDLERS.put(".pptx", new XSLFFileHandler());
+        HANDLERS.put(".pptm", new XSLFFileHandler());
+        HANDLERS.put(".ppsm", new XSLFFileHandler());
+        HANDLERS.put(".ppsx", new XSLFFileHandler());
+        HANDLERS.put(".thmx", new XSLFFileHandler());
 
-		// Visio
-		HANDLERS.put(".vsd", new HDGFFileHandler());
-		
-		// POIFS
-		HANDLERS.put(".ole2", new POIFSFileHandler());
+        // Outlook
+        HANDLERS.put(".msg", new HSMFFileHandler());
 
-		// Microsoft Admin Template?
-		HANDLERS.put(".adm", new HPSFFileHandler());
+        // Publisher
+        HANDLERS.put(".pub", new HPBFFileHandler());
 
-		// Microsoft TNEF
-		HANDLERS.put(".dat", new HMEFFileHandler());
-		
-		// TODO: are these readable by some of the formats?
-		HANDLERS.put(".shw", new NullFileHandler());
-		HANDLERS.put(".zvi", new NullFileHandler());
-		HANDLERS.put(".mpp", new NullFileHandler());
-		HANDLERS.put(".qwp", new NullFileHandler());
-		HANDLERS.put(".wps", new NullFileHandler());
-		HANDLERS.put(".bin", new NullFileHandler());
-		HANDLERS.put(".xps", new NullFileHandler());
-		HANDLERS.put(".sldprt", new NullFileHandler());
-		HANDLERS.put(".mdb", new NullFileHandler());
-		HANDLERS.put(".vml", new NullFileHandler());
+        // Visio - binary
+        HANDLERS.put(".vsd", new HDGFFileHandler());
+        
+        // Visio - ooxml (currently unsupported)
+        HANDLERS.put(".vsdm", new NullFileHandler());
+        HANDLERS.put(".vsdx", new NullFileHandler());
+        HANDLERS.put(".vssm", new NullFileHandler());
+        HANDLERS.put(".vssx", new NullFileHandler());
+        HANDLERS.put(".vstm", new NullFileHandler());
+        HANDLERS.put(".vstx", new NullFileHandler());
 
-		// ignore some file types, images, other formats, ...
-		HANDLERS.put(".txt", new NullFileHandler());
-		HANDLERS.put(".pdf", new NullFileHandler());
-		HANDLERS.put(".rtf", new NullFileHandler());
-		HANDLERS.put(".gif", new NullFileHandler());
-		HANDLERS.put(".html", new NullFileHandler());
-		HANDLERS.put(".png", new NullFileHandler());
-		HANDLERS.put(".wmf", new NullFileHandler());
-		HANDLERS.put(".emf", new NullFileHandler());
-		HANDLERS.put(".dib", new NullFileHandler());
-		HANDLERS.put(".svg", new NullFileHandler());
-		HANDLERS.put(".pict", new NullFileHandler());
-		HANDLERS.put(".jpg", new NullFileHandler());
-		HANDLERS.put(".wav", new NullFileHandler());
-		HANDLERS.put(".pfx", new NullFileHandler());
-		HANDLERS.put(".xml", new NullFileHandler());
-		HANDLERS.put(".csv", new NullFileHandler());
-		
-		// map some files without extension
-		HANDLERS.put("spreadsheet/BigSSTRecord", new NullFileHandler());
+        // POIFS
+        HANDLERS.put(".ole2", new POIFSFileHandler());
+
+        // Microsoft Admin Template?
+        HANDLERS.put(".adm", new HPSFFileHandler());
+
+        // Microsoft TNEF
+        HANDLERS.put(".dat", new HMEFFileHandler());
+
+        // TODO: are these readable by some of the formats?
+        HANDLERS.put(".shw", new NullFileHandler());
+        HANDLERS.put(".zvi", new NullFileHandler());
+        HANDLERS.put(".mpp", new NullFileHandler());
+        HANDLERS.put(".qwp", new NullFileHandler());
+        HANDLERS.put(".wps", new NullFileHandler());
+        HANDLERS.put(".bin", new NullFileHandler());
+        HANDLERS.put(".xps", new NullFileHandler());
+        HANDLERS.put(".sldprt", new NullFileHandler());
+        HANDLERS.put(".mdb", new NullFileHandler());
+        HANDLERS.put(".vml", new NullFileHandler());
+
+        // ignore some file types, images, other formats, ...
+        HANDLERS.put(".txt", new NullFileHandler());
+        HANDLERS.put(".pdf", new NullFileHandler());
+        HANDLERS.put(".rtf", new NullFileHandler());
+        HANDLERS.put(".gif", new NullFileHandler());
+        HANDLERS.put(".html", new NullFileHandler());
+        HANDLERS.put(".png", new NullFileHandler());
+        HANDLERS.put(".wmf", new NullFileHandler());
+        HANDLERS.put(".emf", new NullFileHandler());
+        HANDLERS.put(".dib", new NullFileHandler());
+        HANDLERS.put(".svg", new NullFileHandler());
+        HANDLERS.put(".pict", new NullFileHandler());
+        HANDLERS.put(".jpg", new NullFileHandler());
+        HANDLERS.put(".wav", new NullFileHandler());
+        HANDLERS.put(".pfx", new NullFileHandler());
+        HANDLERS.put(".xml", new NullFileHandler());
+        HANDLERS.put(".csv", new NullFileHandler());
+
+        // map some files without extension
+        HANDLERS.put("spreadsheet/BigSSTRecord", new NullFileHandler());
         HANDLERS.put("spreadsheet/BigSSTRecord2", new NullFileHandler());
         HANDLERS.put("spreadsheet/BigSSTRecord2CR1", new NullFileHandler());
         HANDLERS.put("spreadsheet/BigSSTRecord2CR2", new NullFileHandler());
@@ -151,88 +160,104 @@
         HANDLERS.put("spreadsheet/BigSSTRecord2CR6", new NullFileHandler());
         HANDLERS.put("spreadsheet/BigSSTRecord2CR7", new NullFileHandler());
         HANDLERS.put("spreadsheet/BigSSTRecordCR", new NullFileHandler());
-		HANDLERS.put("spreadsheet/test_properties1", new NullFileHandler());
-	}
+        HANDLERS.put("spreadsheet/test_properties1", new NullFileHandler());
+    }
 
-	private static final Set<String> EXPECTED_FAILURES = new HashSet<String>();
-	static {
-		// password protected files
-		EXPECTED_FAILURES.add("spreadsheet/password.xls");
-		EXPECTED_FAILURES.add("spreadsheet/51832.xls");
-		EXPECTED_FAILURES.add("document/PasswordProtected.doc");
-		EXPECTED_FAILURES.add("slideshow/Password_Protected-hello.ppt");
-		EXPECTED_FAILURES.add("slideshow/Password_Protected-56-hello.ppt");
-		EXPECTED_FAILURES.add("slideshow/Password_Protected-np-hello.ppt");
-		EXPECTED_FAILURES.add("slideshow/cryptoapi-proc2356.ppt");
-		//EXPECTED_FAILURES.add("document/bug53475-password-is-pass.docx");
-		//EXPECTED_FAILURES.add("document/bug53475-password-is-solrcell.docx");
-		EXPECTED_FAILURES.add("spreadsheet/xor-encryption-abc.xls");
+    // Old Word Documents where we can at least extract some text
+    private static final Set<String> OLD_FILES = new HashSet<String>();
+    static {
+        OLD_FILES.add("document/Bug49933.doc");
+        OLD_FILES.add("document/Bug51944.doc");
+        OLD_FILES.add("document/Word6.doc");
+        OLD_FILES.add("document/Word6_sections.doc");
+        OLD_FILES.add("document/Word6_sections2.doc");
+        OLD_FILES.add("document/Word95.doc");
+        OLD_FILES.add("document/word95err.doc");
+        OLD_FILES.add("hpsf/TestMickey.doc");
+        OLD_FILES.add("document/52117.doc");
+    }
+
+    private static final Set<String> EXPECTED_FAILURES = new HashSet<String>();
+    static {
+        // password protected files
+        EXPECTED_FAILURES.add("spreadsheet/password.xls");
+        EXPECTED_FAILURES.add("spreadsheet/protected_passtika.xlsx");
+        EXPECTED_FAILURES.add("spreadsheet/51832.xls");
+        EXPECTED_FAILURES.add("document/PasswordProtected.doc");
+        EXPECTED_FAILURES.add("slideshow/Password_Protected-hello.ppt");
+        EXPECTED_FAILURES.add("slideshow/Password_Protected-56-hello.ppt");
+        EXPECTED_FAILURES.add("slideshow/Password_Protected-np-hello.ppt");
+        EXPECTED_FAILURES.add("slideshow/cryptoapi-proc2356.ppt");
+        //EXPECTED_FAILURES.add("document/bug53475-password-is-pass.docx");
+        //EXPECTED_FAILURES.add("document/bug53475-password-is-solrcell.docx");
+        EXPECTED_FAILURES.add("spreadsheet/xor-encryption-abc.xls");
         EXPECTED_FAILURES.add("spreadsheet/35897-type4.xls");
         //EXPECTED_FAILURES.add("poifs/protect.xlsx");
         //EXPECTED_FAILURES.add("poifs/protected_sha512.xlsx");
         //EXPECTED_FAILURES.add("poifs/extenxls_pwd123.xlsx");
         //EXPECTED_FAILURES.add("poifs/protected_agile.docx");
-		
-		// TODO: fails XMLExportTest, is this ok?
-		EXPECTED_FAILURES.add("spreadsheet/CustomXMLMapping-singleattributenamespace.xlsx");
-		EXPECTED_FAILURES.add("spreadsheet/55864.xlsx");
-		
-		// TODO: these fail now with some NPE/file read error because we now try to compute every value via Cell.toString()!
-		EXPECTED_FAILURES.add("spreadsheet/44958.xls");
-		EXPECTED_FAILURES.add("spreadsheet/44958_1.xls");
-		EXPECTED_FAILURES.add("spreadsheet/testArraysAndTables.xls");
 
-		// TODO: good to ignore?
-		EXPECTED_FAILURES.add("spreadsheet/sample-beta.xlsx");
-		EXPECTED_FAILURES.add("spreadsheet/49931.xls");
-		EXPECTED_FAILURES.add("openxml4j/ContentTypeHasParameters.ooxml");
+        // TODO: fails XMLExportTest, is this ok?
+        EXPECTED_FAILURES.add("spreadsheet/CustomXMLMapping-singleattributenamespace.xlsx");
+        EXPECTED_FAILURES.add("spreadsheet/55864.xlsx");
 
-		// This is actually a spreadsheet!
-		EXPECTED_FAILURES.add("hpsf/TestRobert_Flaherty.doc");
-		
-		// some files that are broken, Excel 5.0/95, Word 95, ...
-		EXPECTED_FAILURES.add("spreadsheet/43493.xls");
-		EXPECTED_FAILURES.add("spreadsheet/46904.xls");
-		EXPECTED_FAILURES.add("document/56880.doc");
-		EXPECTED_FAILURES.add("document/Bug49933.doc");
-		EXPECTED_FAILURES.add("document/Bug50955.doc");
-		EXPECTED_FAILURES.add("document/Bug51944.doc");
-		EXPECTED_FAILURES.add("document/Word6.doc");
-		EXPECTED_FAILURES.add("document/Word6_sections.doc");
-		EXPECTED_FAILURES.add("document/Word6_sections2.doc");
-		EXPECTED_FAILURES.add("document/Word95.doc");
-		EXPECTED_FAILURES.add("document/word95err.doc");
-		EXPECTED_FAILURES.add("hpsf/TestMickey.doc");
-		EXPECTED_FAILURES.add("slideshow/PPT95.ppt");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_NotPresentFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx");
-		EXPECTED_FAILURES.add("openxml4j/OPCCompliance_DerivedPartNameFAIL.docx");
-		EXPECTED_FAILURES.add("spreadsheet/54764-2.xlsx");   // see TestXSSFBugs.bug54764()
-		EXPECTED_FAILURES.add("spreadsheet/54764.xlsx");     // see TestXSSFBugs.bug54764()
+        // TODO: these fail now with some NPE/file read error because we now try to compute every value via Cell.toString()!
+        EXPECTED_FAILURES.add("spreadsheet/44958.xls");
+        EXPECTED_FAILURES.add("spreadsheet/44958_1.xls");
+        EXPECTED_FAILURES.add("spreadsheet/testArraysAndTables.xls");
+
+        // TODO: good to ignore?
+        EXPECTED_FAILURES.add("spreadsheet/sample-beta.xlsx");
+        EXPECTED_FAILURES.add("spreadsheet/49931.xls");
+        EXPECTED_FAILURES.add("openxml4j/ContentTypeHasParameters.ooxml");
+
+        // This is actually a spreadsheet!
+        EXPECTED_FAILURES.add("hpsf/TestRobert_Flaherty.doc");
+
+        // some files that are broken, eg Word 95, ...
+        EXPECTED_FAILURES.add("spreadsheet/43493.xls");
+        EXPECTED_FAILURES.add("spreadsheet/46904.xls");
+        EXPECTED_FAILURES.add("document/56880.doc");
+        EXPECTED_FAILURES.add("document/Bug50955.doc");
+        EXPECTED_FAILURES.add("slideshow/PPT95.ppt");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_NotPresentFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx");
+        EXPECTED_FAILURES.add("openxml4j/OPCCompliance_DerivedPartNameFAIL.docx");
+        EXPECTED_FAILURES.add("spreadsheet/54764-2.xlsx");   // see TestXSSFBugs.bug54764()
+        EXPECTED_FAILURES.add("spreadsheet/54764.xlsx");     // see TestXSSFBugs.bug54764()
         EXPECTED_FAILURES.add("spreadsheet/Simple.xlsb");
+        EXPECTED_FAILURES.add("poifs/unknown_properties.msg"); // POIFS properties corrupted
+        EXPECTED_FAILURES.add("poifs/only-zero-byte-streams.ole2"); // No actual contents
+        
+        // old Excel files, which we only support simple text extraction of
         EXPECTED_FAILURES.add("spreadsheet/testEXCEL_2.xls");
         EXPECTED_FAILURES.add("spreadsheet/testEXCEL_3.xls");
         EXPECTED_FAILURES.add("spreadsheet/testEXCEL_4.xls");
         EXPECTED_FAILURES.add("spreadsheet/testEXCEL_5.xls");
         EXPECTED_FAILURES.add("spreadsheet/testEXCEL_95.xls");
+        
+        // OOXML Strict is not yet supported, see bug #57699
+        EXPECTED_FAILURES.add("spreadsheet/SampleSS.strict.xlsx");
+        EXPECTED_FAILURES.add("spreadsheet/SimpleStrict.xlsx");
+        EXPECTED_FAILURES.add("spreadsheet/sample.strict.xlsx");
 
-		// non-TNEF files
-		EXPECTED_FAILURES.add("ddf/Container.dat");
-		EXPECTED_FAILURES.add("ddf/47143.dat");
-	}
-	
+        // non-TNEF files
+        EXPECTED_FAILURES.add("ddf/Container.dat");
+        EXPECTED_FAILURES.add("ddf/47143.dat");
+    }
+
     @Parameters(name="{index}: {0} using {1}")
     public static Iterable<Object[]> files() {
         DirectoryScanner scanner = new DirectoryScanner();
         scanner.setBasedir(ROOT_DIR);
         scanner.setExcludes(new String[] { "**/.svn/**" });
-        
+
         scanner.scan();
-        
+
         System.out.println("Handling " + scanner.getIncludedFiles().length + " files");
 
         List<Object[]> files = new ArrayList<Object[]>();
@@ -240,47 +265,72 @@
             file = file.replace('\\', '/'); // ... failures/handlers lookup doesn't work on windows otherwise
             files.add(new Object[] { file, HANDLERS.get(getExtension(file)) });
         }
-            
+
         return files;
-     }
-    
+    }
+
     @Parameter(value=0)
     public String file;
-    
+
     @Parameter(value=1)
     public FileHandler handler;
-    
+
     @Test
     public void testAllFiles() throws Exception {
-		assertNotNull("Unknown file extension for file: " + file + ": " + getExtension(file), handler);
-		InputStream stream = new BufferedInputStream(new FileInputStream(new File(ROOT_DIR, file)),100);
-		try {
-			handler.handleFile(stream);
-			
-			assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!", 
-			        EXPECTED_FAILURES.contains(file));
-		} catch (Exception e) {
-		    // check if we expect failure for this file
-			if(!EXPECTED_FAILURES.contains(file)) {
-			    throw new Exception("While handling " + file, e);
-			}
-		} finally {
-			stream.close();
-		}
-	}
+        assertNotNull("Unknown file extension for file: " + file + ": " + getExtension(file), handler);
+        File inputFile = new File(ROOT_DIR, file);
 
-	private static String getExtension(String file) {
-		int pos = file.lastIndexOf('.');
-		if(pos == -1 || pos == file.length()-1) {
-			return file;
-		}
-		
-		return file.substring(pos);
-	}
+        try {
+            InputStream stream = new BufferedInputStream(new FileInputStream(inputFile), 64*1024);
+            try {
+                handler.handleFile(stream);
 
-	private static class NullFileHandler implements FileHandler {
-		@Override
+                assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!", 
+                        OLD_FILES.contains(file));
+            } finally {
+                stream.close();
+            }
+
+            handler.handleExtracting(inputFile);
+
+            assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!", 
+                    EXPECTED_FAILURES.contains(file));
+        } catch (OldWordFileFormatException e) {
+            // for old word files we should still support extracting text
+            if(OLD_FILES.contains(file)) {
+                handler.handleExtracting(inputFile);
+            } else {
+                // check if we expect failure for this file
+                if(!EXPECTED_FAILURES.contains(file) && !AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.contains(file)) {
+                    System.out.println("Failed: " + file);
+                    throw new Exception("While handling " + file, e);
+                }
+            }
+        } catch (Exception e) {
+            // check if we expect failure for this file
+            if(!EXPECTED_FAILURES.contains(file) && !AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.contains(file)) {
+                System.out.println("Failed: " + file);
+                throw new Exception("While handling " + file, e);
+            }
+        }
+    }
+
+    private static String getExtension(String file) {
+        int pos = file.lastIndexOf('.');
+        if(pos == -1 || pos == file.length()-1) {
+            return file;
+        }
+
+        return file.substring(pos);
+    }
+
+    private static class NullFileHandler implements FileHandler {
+        @Override
         public void handleFile(InputStream stream) throws Exception {
-		}
-	}
+        }
+
+        @Override
+        public void handleExtracting(File file) throws Exception {
+        }
+    }
 }
diff --git a/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java b/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java
new file mode 100644
index 0000000..55e2c36
--- /dev/null
+++ b/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java
@@ -0,0 +1,143 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+package org.apache.poi.stress;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertNotNull;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.io.InputStream;

+import java.util.HashSet;

+import java.util.Set;

+import java.util.zip.ZipException;

+

+import org.apache.poi.POIOLE2TextExtractor;

+import org.apache.poi.POITextExtractor;

+import org.apache.poi.dev.OOXMLPrettyPrint;

+import org.apache.poi.extractor.ExtractorFactory;

+import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor;

+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;

+import org.apache.xmlbeans.XmlException;

+

+public abstract class AbstractFileHandler implements FileHandler {

+    public static final Set<String> EXPECTED_EXTRACTOR_FAILURES = new HashSet<String>();

+    static {

+        // password protected files

+        EXPECTED_EXTRACTOR_FAILURES.add("document/bug53475-password-is-pass.docx");

+        EXPECTED_EXTRACTOR_FAILURES.add("poifs/extenxls_pwd123.xlsx");

+        EXPECTED_EXTRACTOR_FAILURES.add("poifs/protect.xlsx");

+        EXPECTED_EXTRACTOR_FAILURES.add("poifs/protected_agile.docx");

+        EXPECTED_EXTRACTOR_FAILURES.add("poifs/protected_sha512.xlsx");

+        

+        // unsupported file-types, no supported OLE2 parts

+        EXPECTED_EXTRACTOR_FAILURES.add("hmef/quick-winmail.dat");

+        EXPECTED_EXTRACTOR_FAILURES.add("hmef/winmail-sample1.dat");

+        EXPECTED_EXTRACTOR_FAILURES.add("hmef/bug52400-winmail-simple.dat");

+        EXPECTED_EXTRACTOR_FAILURES.add("hmef/bug52400-winmail-with-attachments.dat");

+        EXPECTED_EXTRACTOR_FAILURES.add("hpsf/Test0313rur.adm");

+        EXPECTED_EXTRACTOR_FAILURES.add("hsmf/attachment_msg_pdf.msg");

+        EXPECTED_EXTRACTOR_FAILURES.add("poifs/Notes.ole2");

+        EXPECTED_EXTRACTOR_FAILURES.add("slideshow/testPPT.thmx");

+    }

+

+    public void handleExtracting(File file) throws Exception {

+        boolean before = ExtractorFactory.getThreadPrefersEventExtractors();

+        try {

+            ExtractorFactory.setThreadPrefersEventExtractors(true);

+            handleExtractingInternal(file);

+

+            ExtractorFactory.setThreadPrefersEventExtractors(false);

+            handleExtractingInternal(file);

+        } finally {

+            ExtractorFactory.setThreadPrefersEventExtractors(before);

+        }

+        

+        /* Did fail for some documents with special XML contents...

+        try {

+            OOXMLPrettyPrint.main(new String[] { file.getAbsolutePath(), 

+            		"/tmp/pretty-" + file.getName() });

+        } catch (ZipException e) {

+        	// ignore, not a Zip/OOXML file

+        }*/

+    }

+

+    private void handleExtractingInternal(File file) throws Exception {

+        long length = file.length();

+        long modified = file.lastModified();

+        

+        POITextExtractor extractor = ExtractorFactory.createExtractor(file);

+        try  {

+            assertNotNull(extractor);

+

+            assertNotNull(extractor.getText());

+            

+            // also try metadata

+            POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor();

+            assertNotNull(metadataExtractor.getText());

+

+            assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", 

+                    EXPECTED_EXTRACTOR_FAILURES.contains(file));

+            

+            assertEquals("File should not be modified by extractor", length, file.length());

+            assertEquals("File should not be modified by extractor", modified, file.lastModified());

+            

+            handleExtractingAsStream(file);

+            

+            if(extractor instanceof POIOLE2TextExtractor) {

+            	HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor((POIOLE2TextExtractor)extractor);

+            	try {

+                	assertNotNull(hpsfExtractor.getDocumentSummaryInformationText());

+                	assertNotNull(hpsfExtractor.getSummaryInformationText());

+                	String text = hpsfExtractor.getText();

+                	//System.out.println(text);

+                	assertNotNull(text);

+            	} finally {

+            		hpsfExtractor.close();

+            	}

+            }

+        } catch (IllegalArgumentException e) {

+            if(!EXPECTED_EXTRACTOR_FAILURES.contains(file)) {

+                throw new Exception("While handling " + file, e);

+            }

+        } finally {

+            extractor.close();

+        }

+    }

+

+    private void handleExtractingAsStream(File file) throws FileNotFoundException,

+            IOException, InvalidFormatException, OpenXML4JException,

+            XmlException {

+        InputStream stream = new FileInputStream(file);

+        try {

+            POITextExtractor streamExtractor = ExtractorFactory.createExtractor(stream);

+            try {

+                assertNotNull(streamExtractor);

+   

+                assertNotNull(streamExtractor.getText());

+            } finally {

+                streamExtractor.close();

+            }

+        } finally {

+            stream.close();

+        }

+    }

+}

diff --git a/src/integrationtest/org/apache/poi/stress/FileHandler.java b/src/integrationtest/org/apache/poi/stress/FileHandler.java
index e6f3385..ce2991b 100644
--- a/src/integrationtest/org/apache/poi/stress/FileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/FileHandler.java
@@ -16,6 +16,7 @@
 ==================================================================== */
 package org.apache.poi.stress;
 
+import java.io.File;
 import java.io.InputStream;
 
 /**
@@ -34,4 +35,10 @@
 	 * @throws Exception
 	 */
 	void handleFile(InputStream stream) throws Exception;
+	
+	/**
+	 * Ensures that extracting text from the given file
+	 * is returning some text. 
+	 */
+	void handleExtracting(File file) throws Exception;
 }
diff --git a/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java
index 7fac664..b9fe93a 100644
--- a/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HDGFFileHandler.java
@@ -19,10 +19,12 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
 import org.apache.poi.hdgf.HDGFDiagram;
+import org.apache.poi.hdgf.extractor.VisioTextExtractor;
 import org.apache.poi.hdgf.streams.Stream;
 import org.apache.poi.hdgf.streams.TrailerStream;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@@ -48,11 +50,27 @@
 	// a test-case to test this locally without executing the full TestAllFiles
 	@Test
 	public void test() throws Exception {
-		InputStream stream = new FileInputStream("test-data/diagram/44501.vsd");
+		File file = new File("test-data/diagram/44501.vsd");
+
+		InputStream stream = new FileInputStream(file);
 		try {
 			handleFile(stream);
 		} finally {
 			stream.close();
 		}
+		
+		handleExtracting(file);
+		
+		stream = new FileInputStream(file);
+		try {
+			VisioTextExtractor extractor = new VisioTextExtractor(stream);
+			try {
+				assertNotNull(extractor.getText());
+			} finally {
+				extractor.close();
+			}
+		} finally {
+			stream.close();
+		}
 	}
 }
diff --git a/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java
index dfa8750..9f492bf 100644
--- a/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HMEFFileHandler.java
@@ -26,7 +26,7 @@
 import org.apache.poi.hmef.attribute.MAPIStringAttribute;
 import org.junit.Test;
 
-public class HMEFFileHandler implements FileHandler {
+public class HMEFFileHandler extends AbstractFileHandler {
 
 	@Override
     public void handleFile(InputStream stream) throws Exception {
diff --git a/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java
index 31ad8bc..a41b6eb 100644
--- a/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HPBFFileHandler.java
@@ -18,10 +18,12 @@
 
 import static org.junit.Assert.assertNotNull;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
 import org.apache.poi.hpbf.HPBFDocument;
+import org.apache.poi.hpbf.extractor.PublisherTextExtractor;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.junit.Test;
 
@@ -39,11 +41,28 @@
 	// a test-case to test this locally without executing the full TestAllFiles
 	@Test
 	public void test() throws Exception {
-		InputStream stream = new FileInputStream("test-data/publisher/SampleBrochure.pub");
+		File file = new File("test-data/publisher/SampleBrochure.pub");
+
+		InputStream stream = new FileInputStream(file);
 		try {
 			handleFile(stream);
 		} finally {
 			stream.close();
 		}
+		
+		handleExtracting(file);
+		
+		stream = new FileInputStream(file);
+		try {
+			PublisherTextExtractor extractor = new PublisherTextExtractor(stream);
+			try {
+				assertNotNull(extractor.getText());
+			} finally {
+				extractor.close();
+			}
+		} finally {
+			stream.close();
+		}
 	}
+	
 }
diff --git a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
index b7d846a..6a53b2e 100644
--- a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertNotNull;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
@@ -25,7 +26,7 @@
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.junit.Test;
 
-public class HPSFFileHandler implements FileHandler {
+public class HPSFFileHandler extends AbstractFileHandler {
 	@Override
     public void handleFile(InputStream stream) throws Exception {
 		HPSFPropertiesOnlyDocument hpsf = new HPSFPropertiesOnlyDocument(new POIFSFileSystem(stream));
@@ -43,4 +44,10 @@
 			stream.close();
 		}
 	}
+
+    // a test-case to test this locally without executing the full TestAllFiles
+    @Test
+    public void testExtractor() throws Exception {
+        handleExtracting(new File("test-data/hpsf/TestBug44375.xls"));
+    }
 }
diff --git a/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java
index 9de8b79..d68504a 100644
--- a/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HSMFFileHandler.java
@@ -22,6 +22,8 @@
 import java.io.InputStream;
 
 import org.apache.poi.hsmf.MAPIMessage;
+import org.apache.poi.hsmf.datatypes.AttachmentChunks;
+import org.apache.poi.hsmf.datatypes.DirectoryChunk;
 import org.junit.Test;
 
 public class HSMFFileHandler extends POIFSFileHandler {
@@ -32,6 +34,19 @@
 		assertNotNull(mapi.getDisplayBCC());
 		assertNotNull(mapi.getMessageDate());
 
+		AttachmentChunks[] attachments = mapi.getAttachmentFiles();
+
+		for(AttachmentChunks attachment : attachments) {
+
+		   DirectoryChunk chunkDirectory = attachment.attachmentDirectory;
+		   if(chunkDirectory != null) {
+			   MAPIMessage attachmentMSG = chunkDirectory.getAsEmbededMessage();
+			   assertNotNull(attachmentMSG);
+			   String body = attachmentMSG.getTextBody();
+			   assertNotNull(body);
+		   }
+		}
+
 		/* => Writing isn't yet supported...
 		// write out the file
 		File file = TempFile.createTempFile("StressTest", ".msg");
diff --git a/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java
index 19dbd97..dd579c4 100644
--- a/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HSSFFileHandler.java
@@ -16,6 +16,7 @@
 ==================================================================== */
 package org.apache.poi.stress;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
@@ -49,4 +50,10 @@
 			stream.close();
 		}
 	}
+
+	// a test-case to test this locally without executing the full TestAllFiles
+    @Test
+    public void testExtractor() throws Exception {
+        handleExtracting(new File("test-data/spreadsheet/BOOK_in_capitals.xls"));
+    }
 }
\ No newline at end of file
diff --git a/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java
index 1b6d464..a56ddd2 100644
--- a/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HWPFFileHandler.java
@@ -18,12 +18,21 @@
 
 import static org.junit.Assert.assertNotNull;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 
+import org.apache.poi.hdf.extractor.WordDocument;
 import org.apache.poi.hwpf.HWPFDocument;
+import org.apache.poi.hwpf.extractor.WordExtractor;
 import org.junit.Test;
 
+@SuppressWarnings("deprecation")
 public class HWPFFileHandler extends POIFSFileHandler {
 	@Override
 	public void handleFile(InputStream stream) throws Exception {
@@ -33,16 +42,57 @@
 		assertNotNull(doc.getEndnotes());
 		
 		handlePOIDocument(doc);
+		
+		// fails for many documents, but is deprecated anyway... 
+		// handleWordDocument(doc);
+	}
+
+	protected void handleWordDocument(HWPFDocument doc) throws IOException {
+		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+		doc.write(outStream);
+
+		WordDocument wordDoc = new WordDocument(new ByteArrayInputStream(outStream.toByteArray()));
+        
+        StringWriter docTextWriter = new StringWriter();
+        PrintWriter out = new PrintWriter(docTextWriter);
+        try {
+        	wordDoc.writeAllText(out);
+        } finally {
+        	out.close();
+        }
+        docTextWriter.close();
 	}
 
 	// a test-case to test this locally without executing the full TestAllFiles
 	@Test
 	public void test() throws Exception {
-		InputStream stream = new FileInputStream("test-data/document/HeaderFooterUnicode.doc");
+		File file = new File("test-data/document/52117.doc");
+
+		InputStream stream = new FileInputStream(file);
 		try {
 			handleFile(stream);
 		} finally {
 			stream.close();
 		}
+		
+		handleExtracting(file);
+		
+		stream = new FileInputStream(file);
+		try {
+			WordExtractor extractor = new WordExtractor(stream);
+			try {
+				assertNotNull(extractor.getText());
+			} finally {
+				extractor.close();
+			}
+		} finally {
+			stream.close();
+		}
 	}
-}
\ No newline at end of file
+
+	@Test
+	public void testExtractingOld() throws Exception {
+		File file = new File("test-data/document/52117.doc");
+		handleExtracting(file);
+	}
+}
diff --git a/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java b/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java
index 31deac7..5c4a36e 100644
--- a/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/POIFSFileHandler.java
@@ -25,7 +25,7 @@
 import org.apache.poi.POIDocument;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
-public class POIFSFileHandler implements FileHandler {
+public class POIFSFileHandler extends AbstractFileHandler {
 
 	@Override
     public void handleFile(InputStream stream) throws Exception {
diff --git a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
index 103bb9b..7b0821d 100644
--- a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
@@ -20,9 +20,17 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 
 import org.apache.poi.POIXMLDocument;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageAccess;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.poifs.crypt.Decryptor;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.junit.Ignore;
+import org.junit.Test;
 
 public final class POIXMLDocumentHandler {
 	protected void handlePOIXMLDocument(POIXMLDocument doc) throws Exception {
@@ -36,11 +44,33 @@
     protected static boolean isEncrypted(InputStream stream) throws IOException {
         if (POIFSFileSystem.hasPOIFSHeader(stream)) {
             POIFSFileSystem poifs = new POIFSFileSystem(stream);
-            if (poifs.getRoot().hasEntry("EncryptedPackage")) {
+            if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
                 return true;
             }
             throw new IOException("wrong file format or file extension for OO XML file");
         }
         return false;
     }
+	
+	// a test-case to test this locally without executing the full TestAllFiles
+    @Ignore("POIXMLDocument cannot handle this Visio file currently...")
+	@Test
+	public void test() throws Exception {
+		OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ);
+		try {
+			handlePOIXMLDocument(new TestPOIXMLDocument(pkg));
+		} finally {
+			pkg.close();
+		}
+	}
+	
+	private final static class TestPOIXMLDocument extends POIXMLDocument {
+		public TestPOIXMLDocument(OPCPackage pkg) {
+			super(pkg);
+		}
+
+		public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
+			return null;
+		}
+	}
 }
diff --git a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java
index aad703c..f12bbd2 100644
--- a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java
@@ -30,7 +30,7 @@
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.usermodel.WorkbookFactory;
 
-public abstract class SpreadsheetHandler implements FileHandler {
+public abstract class SpreadsheetHandler extends AbstractFileHandler {
 	public void handleWorkbook(Workbook wb, String extension) throws IOException {
 		// try to access some of the content
 		readContent(wb);
diff --git a/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java
index 3464218..2669238 100644
--- a/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java
@@ -18,35 +18,97 @@
 
 import static org.junit.Assert.assertNotNull;
 
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.Drawable;
 import org.apache.poi.xslf.XSLFSlideShow;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xslf.usermodel.XSLFNotes;
+import org.apache.poi.xslf.usermodel.XSLFShape;
+import org.apache.poi.xslf.usermodel.XSLFSlide;
+import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
+import org.apache.poi.xslf.usermodel.XSLFTextShape;
 import org.junit.Test;
 
-public class XSLFFileHandler implements FileHandler {
+public class XSLFFileHandler extends AbstractFileHandler {
 	@Override
     public void handleFile(InputStream stream) throws Exception {
-        // ignore password protected files
-        if (POIXMLDocumentHandler.isEncrypted(stream)) return;
-
         XSLFSlideShow slide = new XSLFSlideShow(OPCPackage.open(stream));
 		assertNotNull(slide.getPresentation());
 		assertNotNull(slide.getSlideMasterReferences());
 		assertNotNull(slide.getSlideReferences());
 		
 		new POIXMLDocumentHandler().handlePOIXMLDocument(slide);
+
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		try {
+		    slide.write(out);
+		} finally {
+		    out.close();
+		}
+		
+        createBitmaps(out);		
 	}
 
+    private void createBitmaps(ByteArrayOutputStream out) throws IOException {
+        XMLSlideShow ppt = new XMLSlideShow(new ByteArrayInputStream(out.toByteArray()));
+        Dimension pgsize = ppt.getPageSize();
+        for (XSLFSlide xmlSlide : ppt.getSlides()) {
+//            System.out.println("slide-" + (i + 1));
+//            System.out.println("" + xmlSlide[i].getTitle());
+
+            BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
+            Graphics2D graphics = img.createGraphics();
+
+            // draw stuff
+            xmlSlide.draw(graphics);
+
+            // Also try to read notes
+            XSLFNotes notes = xmlSlide.getNotes();
+            if(notes != null) {
+                for (XSLFShape note : notes) {
+                    DrawFactory df = DrawFactory.getInstance(graphics);
+                    Drawable d = df.getDrawable(note);
+                    d.draw(graphics);
+                    
+                    if (note instanceof XSLFTextShape) {
+                        XSLFTextShape txShape = (XSLFTextShape) note;
+                        for (XSLFTextParagraph xslfParagraph : txShape.getTextParagraphs()) {
+                            xslfParagraph.getText();
+                        }
+                    }
+                }
+            }
+        }
+        
+        ppt.close();
+    }
+
 	// a test-case to test this locally without executing the full TestAllFiles
 	@Test
 	public void test() throws Exception {
-		InputStream stream = new FileInputStream("test-data/slideshow/testPPT.pptx");
+		InputStream stream = new FileInputStream("test-data/slideshow/SampleShow.pptx");
 		try {
 			handleFile(stream);
 		} finally {
 			stream.close();
 		}
 	}
+
+
+    // a test-case to test this locally without executing the full TestAllFiles
+    @Test
+    public void testExtractor() throws Exception {
+        handleExtracting(new File("test-data/slideshow/testPPT.thmx"));
+    }
 }
\ No newline at end of file
diff --git a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
index 54a386e..a268ed4 100644
--- a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
@@ -17,6 +17,7 @@
 package org.apache.poi.stress;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
@@ -71,4 +72,10 @@
 			stream.close();
 		}
 	}
+
+    // a test-case to test this locally without executing the full TestAllFiles
+    @Test
+    public void testExtractor() throws Exception {
+        handleExtracting(new File("test-data/spreadsheet/56278.xlsx"));
+    }
 }
\ No newline at end of file
diff --git a/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java
index a96d46d..c097dc9 100644
--- a/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/XWPFFileHandler.java
@@ -16,13 +16,15 @@
 ==================================================================== */
 package org.apache.poi.stress;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.io.PushbackInputStream;
 
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.junit.Test;
 
-public class XWPFFileHandler implements FileHandler {
+public class XWPFFileHandler extends AbstractFileHandler {
 	@Override
     public void handleFile(InputStream stream) throws Exception {
         // ignore password protected files
@@ -36,12 +38,16 @@
 	// a test-case to test this locally without executing the full TestAllFiles
 	@Test
 	public void test() throws Exception {
-		InputStream stream = new FileInputStream("test-data/document/footnotes.docx");
+		File file = new File("test-data/document/51921-Word-Crash067.docx");
+
+		InputStream stream = new PushbackInputStream(new FileInputStream(file), 100000);
 		try {
 			handleFile(stream);
 		} finally {
 			stream.close();
 		}
+		
+		handleExtracting(file);
 	}
 	
 }
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/java/org/apache/poi/EmptyFileException.java
similarity index 73%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to src/java/org/apache/poi/EmptyFileException.java
index 48744ec..ddbd142 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/java/org/apache/poi/EmptyFileException.java
@@ -1,22 +1,28 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

-

-       http://www.apache.org/licenses/LICENSE-2.0

-

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

-

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi;
+
+/**
+ * Exception thrown if an Empty (zero byte) file is supplied
+ */
+public class EmptyFileException extends IllegalArgumentException {
+    private static final long serialVersionUID = 1536449292174360166L;
+
+    public EmptyFileException() {
+		super("The supplied file was empty (zero bytes long)");
+	}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/EncryptedDocumentException.java b/src/java/org/apache/poi/EncryptedDocumentException.java
index 12196c8..4ac6123 100644
--- a/src/java/org/apache/poi/EncryptedDocumentException.java
+++ b/src/java/org/apache/poi/EncryptedDocumentException.java
@@ -16,9 +16,10 @@
 ==================================================================== */
 package org.apache.poi;
 
-@SuppressWarnings("serial")
 public class EncryptedDocumentException extends IllegalStateException
 {
+    private static final long serialVersionUID = 7276950444540469193L;
+    
 	public EncryptedDocumentException(String s) {
 		super(s);
 	}
diff --git a/src/java/org/apache/poi/POIDocument.java b/src/java/org/apache/poi/POIDocument.java
index 950e5eb..4345d4b 100644
--- a/src/java/org/apache/poi/POIDocument.java
+++ b/src/java/org/apache/poi/POIDocument.java
@@ -30,14 +30,11 @@
 import org.apache.poi.hpsf.PropertySetFactory;
 import org.apache.poi.hpsf.SummaryInformation;
 import org.apache.poi.poifs.crypt.EncryptionInfo;
-import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
-import org.apache.poi.poifs.filesystem.Entry;
-import org.apache.poi.poifs.filesystem.EntryUtils;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -45,8 +42,6 @@
  * This holds the common functionality for all POI
  *  Document classes.
  * Currently, this relates to Document Information Properties 
- * 
- * @author Nick Burch
  */
 public abstract class POIDocument {
     /** Holds metadata on our document */
@@ -72,20 +67,23 @@
     }
 
     /**
-     * @deprecated use {@link POIDocument#POIDocument(DirectoryNode)} instead 
+     * Constructs from an old-style OPOIFS
      */
-    @Deprecated
-    protected POIDocument(DirectoryNode dir, POIFSFileSystem fs) {
-       this.directory = dir;
-    }
-
-    protected POIDocument(POIFSFileSystem fs) {
+    protected POIDocument(OPOIFSFileSystem fs) {
        this(fs.getRoot());
     }
-    
+    /**
+     * Constructs from an old-style OPOIFS
+     */
     protected POIDocument(NPOIFSFileSystem fs) {
        this(fs.getRoot());
     }
+    /**
+     * Constructs from the default POIFS
+     */
+    protected POIDocument(POIFSFileSystem fs) {
+        this(fs.getRoot());
+     }
 
     /**
      * Fetch the Document Summary Information of the document
@@ -179,12 +177,13 @@
     protected PropertySet getPropertySet(String setName, EncryptionInfo encryptionInfo) {
         DirectoryNode dirNode = directory;
         
+        NPOIFSFileSystem encPoifs = null;
         if (encryptionInfo != null) {
             try {
                 InputStream is = encryptionInfo.getDecryptor().getDataStream(directory);
-                POIFSFileSystem poifs = new POIFSFileSystem(is);
+                encPoifs = new NPOIFSFileSystem(is);
                 is.close();
-                dirNode = poifs.getRoot();
+                dirNode = encPoifs.getRoot();
             } catch (Exception e) {
                 logger.log(POILogger.ERROR, "Error getting encrypted property set with name " + setName, e);
                 return null;
@@ -208,6 +207,11 @@
         try {
             // Create the Property Set
             PropertySet set = PropertySetFactory.create(dis);
+            // Tidy up if needed
+            if (encPoifs != null) {
+                encPoifs.close();
+            }
+            // Return the properties
             return set;
         } catch(IOException ie) {
             // Must be corrupt or something like that
@@ -218,26 +222,39 @@
         }
         return null;
     }
+    
+    /**
+     * Writes out the updated standard Document Information Properties (HPSF)
+     *  into the currently open NPOIFSFileSystem
+     * TODO Implement in-place update
+     * 
+     * @throws IOException if an error when writing to the open
+     *      {@link NPOIFSFileSystem} occurs
+     * TODO throws exception if open from stream not file
+     */
+    protected void writeProperties() throws IOException {
+        throw new IllegalStateException("In-place write is not yet supported");
+    }
 
     /**
-     * Writes out the standard Documment Information Properties (HPSF)
+     * Writes out the standard Document Information Properties (HPSF)
      * @param outFS the POIFSFileSystem to write the properties into
      * 
      * @throws IOException if an error when writing to the 
-     *      {@link POIFSFileSystem} occurs
+     *      {@link NPOIFSFileSystem} occurs
      */
-    protected void writeProperties(POIFSFileSystem outFS) throws IOException {
+    protected void writeProperties(NPOIFSFileSystem outFS) throws IOException {
         writeProperties(outFS, null);
     }
     /**
-     * Writes out the standard Documment Information Properties (HPSF)
-     * @param outFS the POIFSFileSystem to write the properties into
+     * Writes out the standard Document Information Properties (HPSF)
+     * @param outFS the NPOIFSFileSystem to write the properties into
      * @param writtenEntries a list of POIFS entries to add the property names too
      * 
      * @throws IOException if an error when writing to the 
-     *      {@link POIFSFileSystem} occurs
+     *      {@link NPOIFSFileSystem} occurs
      */
-    protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
+    protected void writeProperties(NPOIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
         SummaryInformation si = getSummaryInformation();
         if (si != null) {
             writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME, si, outFS);
@@ -258,12 +275,12 @@
      * Writes out a given ProperySet
      * @param name the (POIFS Level) name of the property to write
      * @param set the PropertySet to write out 
-     * @param outFS the POIFSFileSystem to write the property into
+     * @param outFS the NPOIFSFileSystem to write the property into
      * 
      * @throws IOException if an error when writing to the 
-     *      {@link POIFSFileSystem} occurs
+     *      {@link NPOIFSFileSystem} occurs
      */
-    protected void writePropertySet(String name, PropertySet set, POIFSFileSystem outFS) throws IOException {
+    protected void writePropertySet(String name, PropertySet set, NPOIFSFileSystem outFS) throws IOException {
         try {
             MutablePropertySet mSet = new MutablePropertySet(set);
             ByteArrayOutputStream bOut = new ByteArrayOutputStream();
@@ -288,55 +305,4 @@
      * @throws IOException thrown on errors writing to the stream
      */
     public abstract void write(OutputStream out) throws IOException;
-
-    /**
-     * Copies nodes from one POIFS to the other minus the excepts
-     * @param source is the source POIFS to copy from
-     * @param target is the target POIFS to copy to
-     * @param excepts is a list of Strings specifying what nodes NOT to copy
-     * 
-     * @throws IOException thrown on errors writing to the target file system.
-     * 
-     * @deprecated Use {@link EntryUtils#copyNodes(DirectoryEntry, DirectoryEntry, List)} instead
-     */
-    @Deprecated
-    protected void copyNodes( POIFSFileSystem source, POIFSFileSystem target,
-            List<String> excepts ) throws IOException {
-        EntryUtils.copyNodes( source, target, excepts );
-    }
-
-   /**
-    * Copies nodes from one POIFS to the other minus the excepts
-    * @param sourceRoot is the source POIFS to copy from
-    * @param targetRoot is the target POIFS to copy to
-    * @param excepts is a list of Strings specifying what nodes NOT to copy
-     * 
-     * @throws IOException thrown on errors writing to the target directory node.
-     * 
-    * @deprecated Use {@link EntryUtils#copyNodes(DirectoryEntry, DirectoryEntry, List)} instead
-    */
-    @Deprecated
-    protected void copyNodes( DirectoryNode sourceRoot,
-            DirectoryNode targetRoot, List<String> excepts ) throws IOException
-    {
-        EntryUtils.copyNodes( sourceRoot, targetRoot, excepts );
-    }
-
-    /**
-     * Copies an Entry into a target POIFS directory, recursively
-     * 
-     * @param entry the entry to copy from
-     * @param target the entry to write to
-     * 
-     * @throws IOException thrown on errors writing to the target directory entry.
-     * 
-     * @deprecated Use {@link EntryUtils#copyNodeRecursively(Entry, DirectoryEntry)} instead
-     */
-    @Internal
-    @Deprecated
-    protected void copyNodeRecursively( Entry entry, DirectoryEntry target )
-            throws IOException
-    {
-        EntryUtils.copyNodeRecursively( entry, target );
-    }
 }
diff --git a/src/java/org/apache/poi/POIOLE2TextExtractor.java b/src/java/org/apache/poi/POIOLE2TextExtractor.java
index c0f4cbd..5dd1d75 100644
--- a/src/java/org/apache/poi/POIOLE2TextExtractor.java
+++ b/src/java/org/apache/poi/POIOLE2TextExtractor.java
@@ -20,7 +20,6 @@
 import org.apache.poi.hpsf.SummaryInformation;
 import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 /**
  * Common Parent for OLE2 based Text Extractors
@@ -34,16 +33,28 @@
  * @see org.apache.poi.hwpf.extractor.WordExtractor
  */
 public abstract class POIOLE2TextExtractor extends POITextExtractor {
+	/** The POIDocument that's open */
+	protected POIDocument document;
+
 	/**
 	 * Creates a new text extractor for the given document
 	 * 
 	 * @param document The POIDocument to use in this extractor.
 	 */
 	public POIOLE2TextExtractor(POIDocument document) {
-		super(document);
+		this.document = document;
 	}
 
 	/**
+	 * Creates a new text extractor, using the same
+	 *  document as another text extractor. Normally
+	 *  only used by properties extractors.
+	 */
+	protected POIOLE2TextExtractor(POIOLE2TextExtractor otherExtractor) {
+		this.document = otherExtractor.document;
+	}
+	
+	/**
 	 * Returns the document information metadata for the document
 	 * 
      * @return The Document Summary Information or null 
@@ -81,17 +92,4 @@
     {
         return document.directory;
     }
-
-    /**
-     * Return the underlying POIFS FileSystem of this document.
-     * 
-     * @return the POIFSFileSystem that is associated with the POIDocument of this extractor. 
-     *
-     * @deprecated Use {@link #getRoot()} instead
-     */
-    @Deprecated
-    public POIFSFileSystem getFileSystem()
-    {
-        return document.directory.getFileSystem();
-    }
 }
diff --git a/src/java/org/apache/poi/POITextExtractor.java b/src/java/org/apache/poi/POITextExtractor.java
index e18078b..6514ad5 100644
--- a/src/java/org/apache/poi/POITextExtractor.java
+++ b/src/java/org/apache/poi/POITextExtractor.java
@@ -31,24 +31,6 @@
  * @see org.apache.poi.hwpf.extractor.WordExtractor
  */
 public abstract class POITextExtractor implements Closeable {
-	/** The POIDocument that's open */
-	protected POIDocument document;
-
-	/**
-	 * Creates a new text extractor for the given document
-	 */
-	public POITextExtractor(POIDocument document) {
-		this.document = document;
-	}
-	/**
-	 * Creates a new text extractor, using the same
-	 *  document as another text extractor. Normally
-	 *  only used by properties extractors.
-	 */
-	protected POITextExtractor(POITextExtractor otherExtractor) {
-		this.document = otherExtractor.document;
-	}
-	
 	/**
 	 * Retrieves all the text from the document.
 	 * How cells, paragraphs etc are separated in the text
diff --git a/src/java/org/apache/poi/ddf/EscherPropertyFactory.java b/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
index 3dcce79..efea004 100644
--- a/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
+++ b/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
@@ -82,6 +82,13 @@
                     pos += ((EscherArrayProperty)p).setArrayData(data, pos);
                 } else {
                     byte[] complexData = ((EscherComplexProperty)p).getComplexData();
+
+                    int leftover = data.length-pos;
+                    if(leftover < complexData.length){
+                        throw new IllegalStateException("Could not read complex escher property, lenght was " + complexData.length + ", but had only " +
+                                leftover + " bytes left");
+                    }
+
                     System.arraycopy(data, pos, complexData, 0, complexData.length);
                     pos += complexData.length;
                 }
diff --git a/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java b/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java
index f1b9ca9..9b0f84d 100644
--- a/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java
+++ b/src/java/org/apache/poi/hpsf/HPSFPropertiesOnlyDocument.java
@@ -24,6 +24,7 @@
 import org.apache.poi.POIDocument;
 import org.apache.poi.poifs.filesystem.EntryUtils;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 /**
@@ -36,6 +37,9 @@
     public HPSFPropertiesOnlyDocument(NPOIFSFileSystem fs) {
         super(fs.getRoot());
     }
+    public HPSFPropertiesOnlyDocument(OPOIFSFileSystem fs) {
+        super(fs);
+    }
     public HPSFPropertiesOnlyDocument(POIFSFileSystem fs) {
         super(fs);
     }
@@ -44,7 +48,7 @@
      * Write out, with any properties changes, but nothing else
      */
     public void write(OutputStream out) throws IOException {
-        POIFSFileSystem fs = new POIFSFileSystem();
+        NPOIFSFileSystem fs = new NPOIFSFileSystem();
 
         // For tracking what we've written out, so far
         List<String> excepts = new ArrayList<String>(1);
diff --git a/src/java/org/apache/poi/hpsf/Section.java b/src/java/org/apache/poi/hpsf/Section.java
index 0c97a0e..3c8e5b7 100644
--- a/src/java/org/apache/poi/hpsf/Section.java
+++ b/src/java/org/apache/poi/hpsf/Section.java
@@ -285,7 +285,7 @@
         /*
          * Extract the dictionary (if available).
          */
-        dictionary = (Map) getProperty(0);
+        dictionary = (Map<Long,String>) getProperty(0);
     }
 
 
diff --git a/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java b/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java
index ce5301a..b7967f3 100644
--- a/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java
+++ b/src/java/org/apache/poi/hpsf/extractor/HPSFPropertiesExtractor.java
@@ -23,6 +23,7 @@
 import java.util.Iterator;
 
 import org.apache.poi.POIDocument;
+import org.apache.poi.POIOLE2TextExtractor;
 import org.apache.poi.POITextExtractor;
 import org.apache.poi.hpsf.CustomProperties;
 import org.apache.poi.hpsf.DocumentSummaryInformation;
@@ -39,10 +40,10 @@
  *  build in and custom, returning them in
  *  textual form.
  */
-public class HPSFPropertiesExtractor extends POITextExtractor {
+public class HPSFPropertiesExtractor extends POIOLE2TextExtractor {
     private Closeable toClose;
 
-    public HPSFPropertiesExtractor(POITextExtractor mainExtractor) {
+    public HPSFPropertiesExtractor(POIOLE2TextExtractor mainExtractor) {
         super(mainExtractor);
     }
     public HPSFPropertiesExtractor(POIDocument doc) {
@@ -57,6 +58,10 @@
     }
 
     public String getDocumentSummaryInformationText() {
+        if(document == null) {  // event based extractor does not have a document
+            return "";
+        }
+
         DocumentSummaryInformation dsi = document.getDocumentSummaryInformation();
         StringBuffer text = new StringBuffer();
 
@@ -78,6 +83,10 @@
         return text.toString();
     }
     public String getSummaryInformationText() {
+        if(document == null) {  // event based extractor does not have a document
+            return "";
+        }
+
         SummaryInformation si = document.getSummaryInformation();
 
         // Just normal properties
diff --git a/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java b/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java
index c9f9872..ca35c63 100644
--- a/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java
+++ b/src/java/org/apache/poi/hssf/dev/BiffDrawingToXml.java
@@ -34,7 +34,7 @@
 import org.apache.poi.hssf.record.EscherAggregate;

 import org.apache.poi.hssf.usermodel.HSSFPatriarch;

 import org.apache.poi.hssf.usermodel.HSSFWorkbook;

-import org.apache.poi.poifs.filesystem.POIFSFileSystem;

+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;

 

 /**

  * Utility for representing drawings contained in a binary Excel file as a XML tree

@@ -138,7 +138,7 @@
     }

 

     public static void writeToFile(OutputStream fos, InputStream xlsWorkbook, boolean excludeWorkbookRecords, String[] params) throws IOException {

-        POIFSFileSystem fs = new POIFSFileSystem(xlsWorkbook);

+        NPOIFSFileSystem fs = new NPOIFSFileSystem(xlsWorkbook);

         HSSFWorkbook workbook = new HSSFWorkbook(fs);

         InternalWorkbook internalWorkbook = getInternalWorkbook(workbook);

         DrawingGroupRecord r = (DrawingGroupRecord) internalWorkbook.findFirstRecordBySid(DrawingGroupRecord.sid);

diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
index 5451b27..3afd25a 100644
--- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java
+++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
@@ -17,13 +17,63 @@
 
 package org.apache.poi.hssf.dev;
 
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.hssf.record.*;
 import org.apache.poi.hssf.record.RecordInputStream.LeftoverDataException;
-import org.apache.poi.hssf.record.chart.*;
+import org.apache.poi.hssf.record.chart.AreaFormatRecord;
+import org.apache.poi.hssf.record.chart.AreaRecord;
+import org.apache.poi.hssf.record.chart.AxisLineFormatRecord;
+import org.apache.poi.hssf.record.chart.AxisOptionsRecord;
+import org.apache.poi.hssf.record.chart.AxisParentRecord;
+import org.apache.poi.hssf.record.chart.AxisRecord;
+import org.apache.poi.hssf.record.chart.AxisUsedRecord;
+import org.apache.poi.hssf.record.chart.BarRecord;
+import org.apache.poi.hssf.record.chart.BeginRecord;
+import org.apache.poi.hssf.record.chart.CatLabRecord;
+import org.apache.poi.hssf.record.chart.CategorySeriesAxisRecord;
+import org.apache.poi.hssf.record.chart.ChartEndBlockRecord;
+import org.apache.poi.hssf.record.chart.ChartEndObjectRecord;
+import org.apache.poi.hssf.record.chart.ChartFRTInfoRecord;
+import org.apache.poi.hssf.record.chart.ChartFormatRecord;
+import org.apache.poi.hssf.record.chart.ChartRecord;
+import org.apache.poi.hssf.record.chart.ChartStartBlockRecord;
+import org.apache.poi.hssf.record.chart.ChartStartObjectRecord;
+import org.apache.poi.hssf.record.chart.DatRecord;
+import org.apache.poi.hssf.record.chart.DataFormatRecord;
+import org.apache.poi.hssf.record.chart.DefaultDataLabelTextPropertiesRecord;
+import org.apache.poi.hssf.record.chart.EndRecord;
+import org.apache.poi.hssf.record.chart.FontBasisRecord;
+import org.apache.poi.hssf.record.chart.FontIndexRecord;
+import org.apache.poi.hssf.record.chart.FrameRecord;
+import org.apache.poi.hssf.record.chart.LegendRecord;
+import org.apache.poi.hssf.record.chart.LineFormatRecord;
+import org.apache.poi.hssf.record.chart.LinkedDataRecord;
+import org.apache.poi.hssf.record.chart.ObjectLinkRecord;
+import org.apache.poi.hssf.record.chart.PlotAreaRecord;
+import org.apache.poi.hssf.record.chart.PlotGrowthRecord;
+import org.apache.poi.hssf.record.chart.SeriesIndexRecord;
+import org.apache.poi.hssf.record.chart.SeriesListRecord;
+import org.apache.poi.hssf.record.chart.SeriesRecord;
+import org.apache.poi.hssf.record.chart.SeriesTextRecord;
+import org.apache.poi.hssf.record.chart.SeriesToChartGroupRecord;
+import org.apache.poi.hssf.record.chart.SheetPropertiesRecord;
+import org.apache.poi.hssf.record.chart.TextRecord;
+import org.apache.poi.hssf.record.chart.TickRecord;
+import org.apache.poi.hssf.record.chart.UnitsRecord;
+import org.apache.poi.hssf.record.chart.ValueRangeRecord;
 import org.apache.poi.hssf.record.pivottable.DataItemRecord;
 import org.apache.poi.hssf.record.pivottable.ExtendedPivotTableViewFieldsRecord;
 import org.apache.poi.hssf.record.pivottable.PageItemRecord;
@@ -32,330 +82,330 @@
 import org.apache.poi.hssf.record.pivottable.ViewFieldsRecord;
 import org.apache.poi.hssf.record.pivottable.ViewSourceRecord;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
  *  Utillity for reading in BIFF8 records and displaying data from them.
- *
- *@author     Andrew C. Oliver (acoliver at apache dot org)
- *@author     Glen Stampoultzis (glens at apache.org)
- *@see        #main
+ * @see        #main
  */
 public final class BiffViewer {
-	static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray();
+    static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray();
 
     private BiffViewer() {
-		// no instances of this class
-	}
+        // no instances of this class
+    }
 
-	/**
-	 *  Create an array of records from an input stream
-	 *
-	 *@param  is the InputStream from which the records will be obtained
-	 *@return an array of Records created from the InputStream
-	 *@exception  RecordFormatException  on error processing the InputStream
-	 */
-	public static Record[] createRecords(InputStream is, PrintStream ps, BiffRecordListener recListener, boolean dumpInterpretedRecords)
-			throws RecordFormatException {
-		List<Record> temp = new ArrayList<Record>();
+    /**
+     *  Create an array of records from an input stream
+     *
+     *@param  is the InputStream from which the records will be obtained
+     *@return an array of Records created from the InputStream
+     *@exception  RecordFormatException  on error processing the InputStream
+     */
+    public static Record[] createRecords(InputStream is, PrintStream ps, BiffRecordListener recListener, boolean dumpInterpretedRecords)
+            throws RecordFormatException {
+        List<Record> temp = new ArrayList<Record>();
 
-		RecordInputStream recStream = new RecordInputStream(is);
-		while (true) {
-			boolean hasNext;
-			try {
-				hasNext = recStream.hasNextRecord();
-			} catch (LeftoverDataException e) {
-				e.printStackTrace();
-				System.err.println("Discarding " + recStream.remaining() + " bytes and continuing");
-				recStream.readRemainder();
-				hasNext = recStream.hasNextRecord();
-			}
-			if (!hasNext) {
-				break;
-			}
-			recStream.nextRecord();
-			if (recStream.getSid() == 0) {
-				continue;
-			}
-			Record record;
-			if (dumpInterpretedRecords) {
-				record = createRecord (recStream);
-				if (record.getSid() == ContinueRecord.sid) {
-					continue;
-				}
-				temp.add(record);
+        RecordInputStream recStream = new RecordInputStream(is);
+        while (true) {
+            boolean hasNext;
+            try {
+                hasNext = recStream.hasNextRecord();
+            } catch (LeftoverDataException e) {
+                e.printStackTrace();
+                System.err.println("Discarding " + recStream.remaining() + " bytes and continuing");
+                recStream.readRemainder();
+                hasNext = recStream.hasNextRecord();
+            }
+            if (!hasNext) {
+                break;
+            }
+            recStream.nextRecord();
+            if (recStream.getSid() == 0) {
+                continue;
+            }
+            Record record;
+            if (dumpInterpretedRecords) {
+                record = createRecord (recStream);
+                if (record.getSid() == ContinueRecord.sid) {
+                    continue;
+                }
+                temp.add(record);
 
-				if (dumpInterpretedRecords) {
-					for (String header : recListener.getRecentHeaders()) {
-						ps.println(header);
-					}
-					ps.print(record.toString());
-				}
-			} else {
-				recStream.readRemainder();
-			}
-			ps.println();
-		}
-		Record[] result = new Record[temp.size()];
-		temp.toArray(result);
-		return result;
-	}
+                if (dumpInterpretedRecords) {
+                    for (String header : recListener.getRecentHeaders()) {
+                        ps.println(header);
+                    }
+                    ps.print(record.toString());
+                }
+            } else {
+                recStream.readRemainder();
+            }
+            ps.println();
+        }
+        Record[] result = new Record[temp.size()];
+        temp.toArray(result);
+        return result;
+    }
 
 
-	/**
-	 *  Essentially a duplicate of RecordFactory. Kept separate as not to screw
-	 *  up non-debug operations.
-	 *
-	 */
-	private static Record createRecord(RecordInputStream in) {
-		switch (in.getSid()) {
-			case AreaFormatRecord.sid:     return new AreaFormatRecord(in);
-			case AreaRecord.sid:           return new AreaRecord(in);
-			case ArrayRecord.sid:          return new ArrayRecord(in);
-			case AxisLineFormatRecord.sid: return new AxisLineFormatRecord(in);
-			case AxisOptionsRecord.sid:    return new AxisOptionsRecord(in);
-			case AxisParentRecord.sid:     return new AxisParentRecord(in);
-			case AxisRecord.sid:           return new AxisRecord(in);
-			case AxisUsedRecord.sid:       return new AxisUsedRecord(in);
-			case AutoFilterInfoRecord.sid: return new AutoFilterInfoRecord(in);
-			case BOFRecord.sid:            return new BOFRecord(in);
-			case BackupRecord.sid:         return new BackupRecord(in);
-			case BarRecord.sid:            return new BarRecord(in);
-			case BeginRecord.sid:          return new BeginRecord(in);
-			case BlankRecord.sid:          return new BlankRecord(in);
-			case BookBoolRecord.sid:       return new BookBoolRecord(in);
-			case BoolErrRecord.sid:        return new BoolErrRecord(in);
-			case BottomMarginRecord.sid:   return new BottomMarginRecord(in);
-			case BoundSheetRecord.sid:     return new BoundSheetRecord(in);
-			case CFHeaderRecord.sid:       return new CFHeaderRecord(in);
-			case CFRuleRecord.sid:         return new CFRuleRecord(in);
-			case CalcCountRecord.sid:      return new CalcCountRecord(in);
-			case CalcModeRecord.sid:       return new CalcModeRecord(in);
-			case CategorySeriesAxisRecord.sid: return new CategorySeriesAxisRecord(in);
-			case ChartFormatRecord.sid:    return new ChartFormatRecord(in);
-			case ChartRecord.sid:          return new ChartRecord(in);
-			case CodepageRecord.sid:       return new CodepageRecord(in);
-			case ColumnInfoRecord.sid:     return new ColumnInfoRecord(in);
-			case ContinueRecord.sid:       return new ContinueRecord(in);
-			case CountryRecord.sid:        return new CountryRecord(in);
-			case DBCellRecord.sid:         return new DBCellRecord(in);
-			case DSFRecord.sid:            return new DSFRecord(in);
-			case DatRecord.sid:            return new DatRecord(in);
-			case DataFormatRecord.sid:     return new DataFormatRecord(in);
-			case DateWindow1904Record.sid: return new DateWindow1904Record(in);
-			case DConRefRecord.sid: return new DConRefRecord(in);
-			case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
-			case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
-			case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);
-			case DeltaRecord.sid:          return new DeltaRecord(in);
-			case DimensionsRecord.sid:     return new DimensionsRecord(in);
-			case DrawingGroupRecord.sid:   return new DrawingGroupRecord(in);
-			case DrawingRecordForBiffViewer.sid: return new DrawingRecordForBiffViewer(in);
-			case DrawingSelectionRecord.sid: return new DrawingSelectionRecord(in);
-			case DVRecord.sid:             return new DVRecord(in);
-			case DVALRecord.sid:           return new DVALRecord(in);
-			case EOFRecord.sid:            return new EOFRecord(in);
-			case EndRecord.sid:            return new EndRecord(in);
-			case ExtSSTRecord.sid:         return new ExtSSTRecord(in);
-			case ExtendedFormatRecord.sid: return new ExtendedFormatRecord(in);
-			case ExternSheetRecord.sid:    return new ExternSheetRecord(in);
-			case ExternalNameRecord.sid:   return new ExternalNameRecord(in);
-			case FeatRecord.sid:           return new FeatRecord(in);
-			case FeatHdrRecord.sid:        return new FeatHdrRecord(in);
-			case FilePassRecord.sid:       return new FilePassRecord(in);
-			case FileSharingRecord.sid:    return new FileSharingRecord(in);
-			case FnGroupCountRecord.sid:   return new FnGroupCountRecord(in);
-			case FontBasisRecord.sid:      return new FontBasisRecord(in);
-			case FontIndexRecord.sid:      return new FontIndexRecord(in);
-			case FontRecord.sid:           return new FontRecord(in);
-			case FooterRecord.sid:         return new FooterRecord(in);
-			case FormatRecord.sid:         return new FormatRecord(in);
-			case FormulaRecord.sid:        return new FormulaRecord(in);
-			case FrameRecord.sid:          return new FrameRecord(in);
-			case GridsetRecord.sid:        return new GridsetRecord(in);
-			case GutsRecord.sid:           return new GutsRecord(in);
-			case HCenterRecord.sid:        return new HCenterRecord(in);
-			case HeaderRecord.sid:         return new HeaderRecord(in);
-			case HideObjRecord.sid:        return new HideObjRecord(in);
-			case HorizontalPageBreakRecord.sid: return new HorizontalPageBreakRecord(in);
-			case HyperlinkRecord.sid:      return new HyperlinkRecord(in);
-			case IndexRecord.sid:          return new IndexRecord(in);
-			case InterfaceEndRecord.sid:   return InterfaceEndRecord.create(in);
-			case InterfaceHdrRecord.sid:   return new InterfaceHdrRecord(in);
-			case IterationRecord.sid:      return new IterationRecord(in);
-			case LabelRecord.sid:          return new LabelRecord(in);
-			case LabelSSTRecord.sid:       return new LabelSSTRecord(in);
-			case LeftMarginRecord.sid:     return new LeftMarginRecord(in);
-			case LegendRecord.sid:         return new LegendRecord(in);
-			case LineFormatRecord.sid:     return new LineFormatRecord(in);
-			case LinkedDataRecord.sid:     return new LinkedDataRecord(in);
-			case MMSRecord.sid:            return new MMSRecord(in);
-			case MergeCellsRecord.sid:     return new MergeCellsRecord(in);
-			case MulBlankRecord.sid:       return new MulBlankRecord(in);
-			case MulRKRecord.sid:          return new MulRKRecord(in);
-			case NameRecord.sid:           return new NameRecord(in);
-			case NameCommentRecord.sid:    return new NameCommentRecord(in);
-			case NoteRecord.sid:           return new NoteRecord(in);
-			case NumberRecord.sid:         return new NumberRecord(in);
-			case ObjRecord.sid:            return new ObjRecord(in);
-			case ObjectLinkRecord.sid:     return new ObjectLinkRecord(in);
-			case PaletteRecord.sid:        return new PaletteRecord(in);
-			case PaneRecord.sid:           return new PaneRecord(in);
-			case PasswordRecord.sid:       return new PasswordRecord(in);
-			case PasswordRev4Record.sid:   return new PasswordRev4Record(in);
-			case PlotAreaRecord.sid:       return new PlotAreaRecord(in);
-			case PlotGrowthRecord.sid:     return new PlotGrowthRecord(in);
-			case PrecisionRecord.sid:      return new PrecisionRecord(in);
-			case PrintGridlinesRecord.sid: return new PrintGridlinesRecord(in);
-			case PrintHeadersRecord.sid:   return new PrintHeadersRecord(in);
-			case PrintSetupRecord.sid:     return new PrintSetupRecord(in);
-			case ProtectRecord.sid:        return new ProtectRecord(in);
-			case ProtectionRev4Record.sid: return new ProtectionRev4Record(in);
-			case RKRecord.sid:             return new RKRecord(in);
-			case RecalcIdRecord.sid:       return new RecalcIdRecord(in);
-			case RefModeRecord.sid:        return new RefModeRecord(in);
-			case RefreshAllRecord.sid:     return new RefreshAllRecord(in);
-			case RightMarginRecord.sid:    return new RightMarginRecord(in);
-			case RowRecord.sid:            return new RowRecord(in);
-			case SCLRecord.sid:            return new SCLRecord(in);
-			case SSTRecord.sid:            return new SSTRecord(in);
-			case SaveRecalcRecord.sid:     return new SaveRecalcRecord(in);
-			case SelectionRecord.sid:      return new SelectionRecord(in);
-			case SeriesIndexRecord.sid:    return new SeriesIndexRecord(in);
-			case SeriesListRecord.sid:     return new SeriesListRecord(in);
-			case SeriesRecord.sid:         return new SeriesRecord(in);
-			case SeriesTextRecord.sid:     return new SeriesTextRecord(in);
-			case SeriesToChartGroupRecord.sid: return new SeriesToChartGroupRecord(in);
-			case SharedFormulaRecord.sid:  return new SharedFormulaRecord(in);
-			case SheetPropertiesRecord.sid:return new SheetPropertiesRecord(in);
-			case StringRecord.sid:         return new StringRecord(in);
-			case StyleRecord.sid:          return new StyleRecord(in);
-			case SupBookRecord.sid:        return new SupBookRecord(in);
-			case TabIdRecord.sid:          return new TabIdRecord(in);
-			case TableStylesRecord.sid:    return new TableStylesRecord(in);
-			case TableRecord.sid:          return new TableRecord(in);
-			case TextObjectRecord.sid:     return new TextObjectRecord(in);
-			case TextRecord.sid:           return new TextRecord(in);
-			case TickRecord.sid:           return new TickRecord(in);
-			case TopMarginRecord.sid:      return new TopMarginRecord(in);
-            case UncalcedRecord.sid:       return new UncalcedRecord(in);
-			case UnitsRecord.sid:          return new UnitsRecord(in);
-			case UseSelFSRecord.sid:       return new UseSelFSRecord(in);
-			case VCenterRecord.sid:        return new VCenterRecord(in);
-			case ValueRangeRecord.sid:     return new ValueRangeRecord(in);
-			case VerticalPageBreakRecord.sid: return new VerticalPageBreakRecord(in);
-			case WSBoolRecord.sid:         return new WSBoolRecord(in);
-			case WindowOneRecord.sid:      return new WindowOneRecord(in);
-			case WindowProtectRecord.sid:  return new WindowProtectRecord(in);
-			case WindowTwoRecord.sid:      return new WindowTwoRecord(in);
-			case WriteAccessRecord.sid:    return new WriteAccessRecord(in);
-			case WriteProtectRecord.sid:   return new WriteProtectRecord(in);
+    /**
+     *  Essentially a duplicate of RecordFactory. Kept separate as not to screw
+     *  up non-debug operations.
+     *
+     */
+    private static Record createRecord(RecordInputStream in) {
+        switch (in.getSid()) {
+            case AreaFormatRecord.sid:        return new AreaFormatRecord(in);
+            case AreaRecord.sid:              return new AreaRecord(in);
+            case ArrayRecord.sid:             return new ArrayRecord(in);
+            case AxisLineFormatRecord.sid:    return new AxisLineFormatRecord(in);
+            case AxisOptionsRecord.sid:       return new AxisOptionsRecord(in);
+            case AxisParentRecord.sid:        return new AxisParentRecord(in);
+            case AxisRecord.sid:              return new AxisRecord(in);
+            case AxisUsedRecord.sid:          return new AxisUsedRecord(in);
+            case AutoFilterInfoRecord.sid:    return new AutoFilterInfoRecord(in);
+            case BOFRecord.sid:               return new BOFRecord(in);
+            case BackupRecord.sid:            return new BackupRecord(in);
+            case BarRecord.sid:               return new BarRecord(in);
+            case BeginRecord.sid:             return new BeginRecord(in);
+            case BlankRecord.sid:             return new BlankRecord(in);
+            case BookBoolRecord.sid:          return new BookBoolRecord(in);
+            case BoolErrRecord.sid:           return new BoolErrRecord(in);
+            case BottomMarginRecord.sid:      return new BottomMarginRecord(in);
+            case BoundSheetRecord.sid:        return new BoundSheetRecord(in);
+            case CFHeaderRecord.sid:          return new CFHeaderRecord(in);
+            case CFHeader12Record.sid:        return new CFHeader12Record(in);
+            case CFRuleRecord.sid:            return new CFRuleRecord(in);
+            case CFRule12Record.sid:          return new CFRule12Record(in);
+            // TODO Add CF Ex, and remove from UnknownRecord 
+            case CalcCountRecord.sid:         return new CalcCountRecord(in);
+            case CalcModeRecord.sid:          return new CalcModeRecord(in);
+            case CategorySeriesAxisRecord.sid:return new CategorySeriesAxisRecord(in);
+            case ChartFormatRecord.sid:       return new ChartFormatRecord(in);
+            case ChartRecord.sid:             return new ChartRecord(in);
+            case CodepageRecord.sid:          return new CodepageRecord(in);
+            case ColumnInfoRecord.sid:        return new ColumnInfoRecord(in);
+            case ContinueRecord.sid:          return new ContinueRecord(in);
+            case CountryRecord.sid:           return new CountryRecord(in);
+            case DBCellRecord.sid:            return new DBCellRecord(in);
+            case DSFRecord.sid:               return new DSFRecord(in);
+            case DatRecord.sid:               return new DatRecord(in);
+            case DataFormatRecord.sid:        return new DataFormatRecord(in);
+            case DateWindow1904Record.sid:    return new DateWindow1904Record(in);
+            case DConRefRecord.sid:           return new DConRefRecord(in);
+            case DefaultColWidthRecord.sid:   return new DefaultColWidthRecord(in);
+            case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
+            case DefaultRowHeightRecord.sid:  return new DefaultRowHeightRecord(in);
+            case DeltaRecord.sid:             return new DeltaRecord(in);
+            case DimensionsRecord.sid:        return new DimensionsRecord(in);
+            case DrawingGroupRecord.sid:      return new DrawingGroupRecord(in);
+            case DrawingRecordForBiffViewer.sid: return new DrawingRecordForBiffViewer(in);
+            case DrawingSelectionRecord.sid:  return new DrawingSelectionRecord(in);
+            case DVRecord.sid:                return new DVRecord(in);
+            case DVALRecord.sid:              return new DVALRecord(in);
+            case EOFRecord.sid:               return new EOFRecord(in);
+            case EndRecord.sid:               return new EndRecord(in);
+            case ExtSSTRecord.sid:            return new ExtSSTRecord(in);
+            case ExtendedFormatRecord.sid:    return new ExtendedFormatRecord(in);
+            case ExternSheetRecord.sid:       return new ExternSheetRecord(in);
+            case ExternalNameRecord.sid:      return new ExternalNameRecord(in);
+            case FeatRecord.sid:              return new FeatRecord(in);
+            case FeatHdrRecord.sid:           return new FeatHdrRecord(in);
+            case FilePassRecord.sid:          return new FilePassRecord(in);
+            case FileSharingRecord.sid:       return new FileSharingRecord(in);
+            case FnGroupCountRecord.sid:      return new FnGroupCountRecord(in);
+            case FontBasisRecord.sid:         return new FontBasisRecord(in);
+            case FontIndexRecord.sid:         return new FontIndexRecord(in);
+            case FontRecord.sid:              return new FontRecord(in);
+            case FooterRecord.sid:            return new FooterRecord(in);
+            case FormatRecord.sid:            return new FormatRecord(in);
+            case FormulaRecord.sid:           return new FormulaRecord(in);
+            case FrameRecord.sid:             return new FrameRecord(in);
+            case GridsetRecord.sid:           return new GridsetRecord(in);
+            case GutsRecord.sid:              return new GutsRecord(in);
+            case HCenterRecord.sid:           return new HCenterRecord(in);
+            case HeaderRecord.sid:            return new HeaderRecord(in);
+            case HideObjRecord.sid:           return new HideObjRecord(in);
+            case HorizontalPageBreakRecord.sid: return new HorizontalPageBreakRecord(in);
+            case HyperlinkRecord.sid:         return new HyperlinkRecord(in);
+            case IndexRecord.sid:             return new IndexRecord(in);
+            case InterfaceEndRecord.sid:      return InterfaceEndRecord.create(in);
+            case InterfaceHdrRecord.sid:      return new InterfaceHdrRecord(in);
+            case IterationRecord.sid:         return new IterationRecord(in);
+            case LabelRecord.sid:             return new LabelRecord(in);
+            case LabelSSTRecord.sid:          return new LabelSSTRecord(in);
+            case LeftMarginRecord.sid:        return new LeftMarginRecord(in);
+            case LegendRecord.sid:            return new LegendRecord(in);
+            case LineFormatRecord.sid:        return new LineFormatRecord(in);
+            case LinkedDataRecord.sid:        return new LinkedDataRecord(in);
+            case MMSRecord.sid:               return new MMSRecord(in);
+            case MergeCellsRecord.sid:        return new MergeCellsRecord(in);
+            case MulBlankRecord.sid:          return new MulBlankRecord(in);
+            case MulRKRecord.sid:             return new MulRKRecord(in);
+            case NameRecord.sid:              return new NameRecord(in);
+            case NameCommentRecord.sid:       return new NameCommentRecord(in);
+            case NoteRecord.sid:              return new NoteRecord(in);
+            case NumberRecord.sid:            return new NumberRecord(in);
+            case ObjRecord.sid:               return new ObjRecord(in);
+            case ObjectLinkRecord.sid:        return new ObjectLinkRecord(in);
+            case PaletteRecord.sid:           return new PaletteRecord(in);
+            case PaneRecord.sid:              return new PaneRecord(in);
+            case PasswordRecord.sid:          return new PasswordRecord(in);
+            case PasswordRev4Record.sid:      return new PasswordRev4Record(in);
+            case PlotAreaRecord.sid:          return new PlotAreaRecord(in);
+            case PlotGrowthRecord.sid:        return new PlotGrowthRecord(in);
+            case PrecisionRecord.sid:         return new PrecisionRecord(in);
+            case PrintGridlinesRecord.sid:    return new PrintGridlinesRecord(in);
+            case PrintHeadersRecord.sid:      return new PrintHeadersRecord(in);
+            case PrintSetupRecord.sid:        return new PrintSetupRecord(in);
+            case ProtectRecord.sid:           return new ProtectRecord(in);
+            case ProtectionRev4Record.sid:    return new ProtectionRev4Record(in);
+            case RKRecord.sid:                return new RKRecord(in);
+            case RecalcIdRecord.sid:          return new RecalcIdRecord(in);
+            case RefModeRecord.sid:           return new RefModeRecord(in);
+            case RefreshAllRecord.sid:        return new RefreshAllRecord(in);
+            case RightMarginRecord.sid:       return new RightMarginRecord(in);
+            case RowRecord.sid:               return new RowRecord(in);
+            case SCLRecord.sid:               return new SCLRecord(in);
+            case SSTRecord.sid:               return new SSTRecord(in);
+            case SaveRecalcRecord.sid:        return new SaveRecalcRecord(in);
+            case SelectionRecord.sid:         return new SelectionRecord(in);
+            case SeriesIndexRecord.sid:       return new SeriesIndexRecord(in);
+            case SeriesListRecord.sid:        return new SeriesListRecord(in);
+            case SeriesRecord.sid:            return new SeriesRecord(in);
+            case SeriesTextRecord.sid:        return new SeriesTextRecord(in);
+            case SeriesToChartGroupRecord.sid:return new SeriesToChartGroupRecord(in);
+            case SharedFormulaRecord.sid:     return new SharedFormulaRecord(in);
+            case SheetPropertiesRecord.sid:   return new SheetPropertiesRecord(in);
+            case StringRecord.sid:            return new StringRecord(in);
+            case StyleRecord.sid:             return new StyleRecord(in);
+            case SupBookRecord.sid:           return new SupBookRecord(in);
+            case TabIdRecord.sid:             return new TabIdRecord(in);
+            case TableStylesRecord.sid:       return new TableStylesRecord(in);
+            case TableRecord.sid:             return new TableRecord(in);
+            case TextObjectRecord.sid:        return new TextObjectRecord(in);
+            case TextRecord.sid:              return new TextRecord(in);
+            case TickRecord.sid:              return new TickRecord(in);
+            case TopMarginRecord.sid:         return new TopMarginRecord(in);
+            case UncalcedRecord.sid:          return new UncalcedRecord(in);
+            case UnitsRecord.sid:             return new UnitsRecord(in);
+            case UseSelFSRecord.sid:          return new UseSelFSRecord(in);
+            case VCenterRecord.sid:           return new VCenterRecord(in);
+            case ValueRangeRecord.sid:        return new ValueRangeRecord(in);
+            case VerticalPageBreakRecord.sid: return new VerticalPageBreakRecord(in);
+            case WSBoolRecord.sid:            return new WSBoolRecord(in);
+            case WindowOneRecord.sid:         return new WindowOneRecord(in);
+            case WindowProtectRecord.sid:     return new WindowProtectRecord(in);
+            case WindowTwoRecord.sid:         return new WindowTwoRecord(in);
+            case WriteAccessRecord.sid:       return new WriteAccessRecord(in);
+            case WriteProtectRecord.sid:      return new WriteProtectRecord(in);
 
-			// chart
-			case CatLabRecord.sid:         return new CatLabRecord(in);
-			case ChartEndBlockRecord.sid:  return new ChartEndBlockRecord(in);
-			case ChartEndObjectRecord.sid: return new ChartEndObjectRecord(in);
-			case ChartFRTInfoRecord.sid:   return new ChartFRTInfoRecord(in);
-			case ChartStartBlockRecord.sid: return new ChartStartBlockRecord(in);
-			case ChartStartObjectRecord.sid: return new ChartStartObjectRecord(in);
+            // chart
+            case CatLabRecord.sid:            return new CatLabRecord(in);
+            case ChartEndBlockRecord.sid:     return new ChartEndBlockRecord(in);
+            case ChartEndObjectRecord.sid:    return new ChartEndObjectRecord(in);
+            case ChartFRTInfoRecord.sid:      return new ChartFRTInfoRecord(in);
+            case ChartStartBlockRecord.sid:   return new ChartStartBlockRecord(in);
+            case ChartStartObjectRecord.sid:  return new ChartStartObjectRecord(in);
 
-			// pivot table
-			case StreamIDRecord.sid:        return new StreamIDRecord(in);
-			case ViewSourceRecord.sid:      return new ViewSourceRecord(in);
-			case PageItemRecord.sid:        return new PageItemRecord(in);
-			case ViewDefinitionRecord.sid:  return new ViewDefinitionRecord(in);
-			case ViewFieldsRecord.sid:      return new ViewFieldsRecord(in);
-			case DataItemRecord.sid:        return new DataItemRecord(in);
-			case ExtendedPivotTableViewFieldsRecord.sid: return new ExtendedPivotTableViewFieldsRecord(in);
-		}
-		return new UnknownRecord(in);
-	}
+            // pivot table
+            case StreamIDRecord.sid:           return new StreamIDRecord(in);
+            case ViewSourceRecord.sid:         return new ViewSourceRecord(in);
+            case PageItemRecord.sid:           return new PageItemRecord(in);
+            case ViewDefinitionRecord.sid:     return new ViewDefinitionRecord(in);
+            case ViewFieldsRecord.sid:         return new ViewFieldsRecord(in);
+            case DataItemRecord.sid:           return new DataItemRecord(in);
+            case ExtendedPivotTableViewFieldsRecord.sid: return new ExtendedPivotTableViewFieldsRecord(in);
+        }
+        return new UnknownRecord(in);
+    }
 
-	private static final class CommandArgs {
+    private static final class CommandArgs {
 
-		private final boolean _biffhex;
-		private final boolean _noint;
-		private final boolean _out;
-		private final boolean _rawhex;
-		private final boolean _noHeader;
-		private final File _file;
+        private final boolean _biffhex;
+        private final boolean _noint;
+        private final boolean _out;
+        private final boolean _rawhex;
+        private final boolean _noHeader;
+        private final File _file;
 
-		private CommandArgs(boolean biffhex, boolean noint, boolean out, boolean rawhex, boolean noHeader, File file) {
-			_biffhex = biffhex;
-			_noint = noint;
-			_out = out;
-			_rawhex = rawhex;
-			_file = file;
-			_noHeader = noHeader;
-		}
+        private CommandArgs(boolean biffhex, boolean noint, boolean out, boolean rawhex, boolean noHeader, File file) {
+            _biffhex = biffhex;
+            _noint = noint;
+            _out = out;
+            _rawhex = rawhex;
+            _file = file;
+            _noHeader = noHeader;
+        }
 
-		public static CommandArgs parse(String[] args) throws CommandParseException {
-			int nArgs = args.length;
-			boolean biffhex = false;
-			boolean noint = false;
-			boolean out = false;
-			boolean rawhex = false;
-			boolean noheader = false;
-			File file = null;
-			for (int i=0; i<nArgs; i++) {
-				String arg = args[i];
-				if (arg.startsWith("--")) {
-					if ("--biffhex".equals(arg)) {
-						biffhex = true;
-					} else if ("--noint".equals(arg)) {
-						noint = true;
-					} else if ("--out".equals(arg)) {
-						out = true;
-					} else if ("--escher".equals(arg)) {
-						System.setProperty("poi.deserialize.escher", "true");
-					} else if ("--rawhex".equals(arg)) {
-						rawhex = true;
-					} else if ("--noheader".equals(arg)) {
-						noheader = true;
-					} else {
-						throw new CommandParseException("Unexpected option '" + arg + "'");
-					}
-					continue;
-				}
-				file = new File(arg);
-				if (!file.exists()) {
-					throw new CommandParseException("Specified file '" + arg + "' does not exist");
-				}
-				if (i+1<nArgs) {
-					throw new CommandParseException("File name must be the last arg");
-				}
-			}
-			if (file == null) {
-				throw new CommandParseException("Biff viewer needs a filename");
-			}
-			return new CommandArgs(biffhex, noint, out, rawhex, noheader, file);
-		}
-		public boolean shouldDumpBiffHex() {
-			return _biffhex;
-		}
-		public boolean shouldDumpRecordInterpretations() {
-			return !_noint;
-		}
-		public boolean shouldOutputToFile() {
-			return _out;
-		}
-		public boolean shouldOutputRawHexOnly() {
-			return _rawhex;
-		}
-		public boolean suppressHeader() {
-			return _noHeader;
-		}
-		public File getFile() {
-			return _file;
-		}
-	}
-	private static final class CommandParseException extends Exception {
-		public CommandParseException(String msg) {
-			super(msg);
-		}
-	}
+        public static CommandArgs parse(String[] args) throws CommandParseException {
+            int nArgs = args.length;
+            boolean biffhex = false;
+            boolean noint = false;
+            boolean out = false;
+            boolean rawhex = false;
+            boolean noheader = false;
+            File file = null;
+            for (int i=0; i<nArgs; i++) {
+                String arg = args[i];
+                if (arg.startsWith("--")) {
+                    if ("--biffhex".equals(arg)) {
+                        biffhex = true;
+                    } else if ("--noint".equals(arg)) {
+                        noint = true;
+                    } else if ("--out".equals(arg)) {
+                        out = true;
+                    } else if ("--escher".equals(arg)) {
+                        System.setProperty("poi.deserialize.escher", "true");
+                    } else if ("--rawhex".equals(arg)) {
+                        rawhex = true;
+                    } else if ("--noheader".equals(arg)) {
+                        noheader = true;
+                    } else {
+                        throw new CommandParseException("Unexpected option '" + arg + "'");
+                    }
+                    continue;
+                }
+                file = new File(arg);
+                if (!file.exists()) {
+                    throw new CommandParseException("Specified file '" + arg + "' does not exist");
+                }
+                if (i+1<nArgs) {
+                    throw new CommandParseException("File name must be the last arg");
+                }
+            }
+            if (file == null) {
+                throw new CommandParseException("Biff viewer needs a filename");
+            }
+            return new CommandArgs(biffhex, noint, out, rawhex, noheader, file);
+        }
+        public boolean shouldDumpBiffHex() {
+            return _biffhex;
+        }
+        public boolean shouldDumpRecordInterpretations() {
+            return !_noint;
+        }
+        public boolean shouldOutputToFile() {
+            return _out;
+        }
+        public boolean shouldOutputRawHexOnly() {
+            return _rawhex;
+        }
+        public boolean suppressHeader() {
+            return _noHeader;
+        }
+        public File getFile() {
+            return _file;
+        }
+    }
+    private static final class CommandParseException extends Exception {
+        public CommandParseException(String msg) {
+            super(msg);
+        }
+    }
 
 	/**
 	 * Method main with 1 argument just run straight biffview against given
@@ -420,7 +470,7 @@
 
 	protected static InputStream getPOIFSInputStream(File file)
 			throws IOException, FileNotFoundException {
-		POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file));
+		NPOIFSFileSystem fs = new NPOIFSFileSystem(new FileInputStream(file));
 		String workbookName = HSSFWorkbook.getWorkbookDirEntryName(fs.getRoot());
 		return fs.createDocumentInputStream(workbookName);
 	}
diff --git a/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java b/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java
index 45ab8d8..4d0b894 100644
--- a/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java
+++ b/src/java/org/apache/poi/hssf/eventusermodel/HSSFEventFactory.java
@@ -19,6 +19,7 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.util.Set;
 
 import org.apache.poi.hssf.eventusermodel.HSSFUserException;
 import org.apache.poi.hssf.record.*;
@@ -56,11 +57,24 @@
     * @param req an Instance of HSSFRequest which has your registered listeners
     * @param dir  a DirectoryNode containing your workbook
     */
-   public void processWorkbookEvents(HSSFRequest req, DirectoryNode dir) throws IOException {
-      InputStream in = dir.createDocumentInputStream("Workbook");
+    public void processWorkbookEvents(HSSFRequest req, DirectoryNode dir) throws IOException {
+        // some old documents have "WORKBOOK" or "BOOK"
+        final String name;
+        Set<String> entryNames = dir.getEntryNames();
+        if (entryNames.contains("Workbook")) {
+            name = "Workbook";
+        } else if (entryNames.contains("WORKBOOK")) {
+            name = "WORKBOOK";
+        } else if (entryNames.contains("BOOK")) {
+            name = "BOOK";
+        } else {
+            name = "Workbook";
+        }
 
-      processEvents(req, in);
-   }
+        InputStream in = dir.createDocumentInputStream(name);
+
+        processEvents(req, in);
+    }
 
    /**
     * Processes a file into essentially record events.
diff --git a/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java b/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java
index 889de20..4220ca2 100644
--- a/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java
+++ b/src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.poi.POIDocument;
 import org.apache.poi.POIOLE2TextExtractor;
 import org.apache.poi.hpsf.DocumentSummaryInformation;
 import org.apache.poi.hpsf.SummaryInformation;
@@ -75,7 +76,7 @@
 
     public EventBasedExcelExtractor( DirectoryNode dir )
     {
-        super( null );
+        super( (POIDocument)null );
         _dir = dir;
     }
 
@@ -84,16 +85,6 @@
    }
 
    /**
-    * Return the underlying POIFS FileSystem of
-    *  this document.
-    *
-    * @deprecated Use {@link #getRoot()} instead
-    */
-   public POIFSFileSystem getFileSystem() {
-      return _dir.getFileSystem();
-   }
-
-   /**
     * Would return the document information metadata for the document,
     *  if we supported it
     */
diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
index 3c3b91b..a267097 100644
--- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
+++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
@@ -774,11 +774,12 @@
             }
         }
         
-        // also tell the LinkTable about the removed sheet
-        // +1 because we already removed it from the count of sheets!
-        for(int i = sheetIndex+1;i < getNumSheets()+1;i++) {
-            // also update the link-table as otherwise references might point at invalid sheets
-            linkTable.removeSheet(i);
+        if (linkTable != null) {
+            // also tell the LinkTable about the removed sheet
+            // +1 because we already removed it from the count of sheets!
+            for(int i = sheetIndex+1;i < getNumSheets()+1;i++) {
+                linkTable.removeSheet(i);
+            }
         }
     }
 
diff --git a/src/java/org/apache/poi/hssf/record/CFHeader12Record.java b/src/java/org/apache/poi/hssf/record/CFHeader12Record.java
new file mode 100644
index 0000000..89c4421
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/CFHeader12Record.java
@@ -0,0 +1,88 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.hssf.record.common.FutureRecord;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Conditional Formatting Header v12 record CFHEADER12 (0x0879),
+ *  for conditional formattings introduced in Excel 2007 and newer.
+ */
+public final class CFHeader12Record extends CFHeaderBase implements FutureRecord {
+    public static final short sid = 0x0879;
+
+    private FtrHeader futureHeader;
+
+    /** Creates new CFHeaderRecord */
+    public CFHeader12Record() {
+        createEmpty();
+        futureHeader = new FtrHeader();
+        futureHeader.setRecordType(sid);
+    }
+    public CFHeader12Record(CellRangeAddress[] regions, int nRules) {
+        super(regions, nRules);
+        futureHeader = new FtrHeader();
+        futureHeader.setRecordType(sid);
+    }
+    public CFHeader12Record(RecordInputStream in) {
+        futureHeader = new FtrHeader(in);
+        read(in);
+    }
+
+    @Override
+    protected String getRecordName() {
+        return "CFHEADER12";
+    }
+
+    protected int getDataSize() {
+        return FtrHeader.getDataSize() + super.getDataSize();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        // Sync the associated range
+        futureHeader.setAssociatedRange(getEnclosingCellRange());
+        // Write the future header first
+        futureHeader.serialize(out);
+        // Then the rest of the CF Header details
+        super.serialize(out);
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public short getFutureRecordType() {
+        return futureHeader.getRecordType();
+    }
+    public FtrHeader getFutureHeader() {
+        return futureHeader;
+    }
+    public CellRangeAddress getAssociatedRange() {
+        return futureHeader.getAssociatedRange();
+    }
+    
+    public Object clone() {
+        CFHeader12Record result = new CFHeader12Record();
+        result.futureHeader = (FtrHeader)futureHeader.clone();
+        super.copyTo(result);
+        return result;
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderBase.java b/src/java/org/apache/poi/hssf/record/CFHeaderBase.java
new file mode 100644
index 0000000..4e40a34
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/CFHeaderBase.java
@@ -0,0 +1,153 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.cf.CellRangeUtil;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Parent of Conditional Formatting Header records,
+ *  {@link CFHeaderRecord} and {@link CFHeader12Record}.
+ */
+public abstract class CFHeaderBase extends StandardRecord {
+    private int field_1_numcf;
+    private int field_2_need_recalculation_and_id;
+    private CellRangeAddress field_3_enclosing_cell_range;
+    private CellRangeAddressList field_4_cell_ranges;
+
+    /** Creates new CFHeaderBase */
+    protected CFHeaderBase() {
+    }
+    protected CFHeaderBase(CellRangeAddress[] regions, int nRules) {
+        CellRangeAddress[] unmergedRanges = regions;
+        CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges);
+        setCellRanges(mergeCellRanges);
+        field_1_numcf = nRules;
+    }
+
+    protected void createEmpty() {
+        field_3_enclosing_cell_range = new CellRangeAddress(0, 0, 0, 0);
+        field_4_cell_ranges = new CellRangeAddressList();
+    }
+    protected void read(RecordInputStream in) {
+        field_1_numcf = in.readShort();
+        field_2_need_recalculation_and_id = in.readShort();
+        field_3_enclosing_cell_range = new CellRangeAddress(in);
+        field_4_cell_ranges = new CellRangeAddressList(in);
+    }
+
+    public int getNumberOfConditionalFormats() {
+        return field_1_numcf;
+    }
+    public void setNumberOfConditionalFormats(int n) {
+        field_1_numcf=n;
+    }
+
+    public boolean getNeedRecalculation() {
+        // Held on the 1st bit
+        return field_2_need_recalculation_and_id % 2 == 1;
+    }
+    public void setNeedRecalculation(boolean b) {
+        // held on the first bit
+        if (b == getNeedRecalculation()) return;
+        if (b) field_2_need_recalculation_and_id++;
+        else   field_2_need_recalculation_and_id--;
+    }
+
+    public int getID() {
+        // Remaining 15 bits of field 2
+        return field_2_need_recalculation_and_id>>1;
+    }
+    public void setID(int id) {
+        // Remaining 15 bits of field 2
+        boolean needsRecalc = getNeedRecalculation();
+        field_2_need_recalculation_and_id = (id<<1);
+        if (needsRecalc) field_2_need_recalculation_and_id++;
+    }
+
+    public CellRangeAddress getEnclosingCellRange() {
+        return field_3_enclosing_cell_range;
+    }
+    public void setEnclosingCellRange(CellRangeAddress cr) {
+        field_3_enclosing_cell_range = cr;
+    }
+
+    /**
+     * Set cell ranges list to a single cell range and 
+     * modify the enclosing cell range accordingly.
+     * @param cellRanges - list of CellRange objects
+     */
+    public void setCellRanges(CellRangeAddress[] cellRanges) {
+        if(cellRanges == null) {
+            throw new IllegalArgumentException("cellRanges must not be null");
+        }
+        CellRangeAddressList cral = new CellRangeAddressList();
+        CellRangeAddress enclosingRange = null;
+        for (int i = 0; i < cellRanges.length; i++) {
+            CellRangeAddress cr = cellRanges[i];
+            enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange);
+            cral.addCellRangeAddress(cr);
+        }
+        field_3_enclosing_cell_range = enclosingRange;
+        field_4_cell_ranges = cral;
+    }
+
+    public CellRangeAddress[] getCellRanges() {
+        return field_4_cell_ranges.getCellRangeAddresses();
+    }
+
+    protected abstract String getRecordName();
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[").append(getRecordName()).append("]\n");
+        buffer.append("\t.numCF             = ").append(getNumberOfConditionalFormats()).append("\n");
+        buffer.append("\t.needRecalc        = ").append(getNeedRecalculation()).append("\n");
+        buffer.append("\t.id                = ").append(getID()).append("\n");
+        buffer.append("\t.enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
+        buffer.append("\t.cfranges=[");
+        for( int i=0; i<field_4_cell_ranges.countRanges(); i++) {
+            buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
+        }
+        buffer.append("]\n");
+        buffer.append("[/").append(getRecordName()).append("]\n");
+        return buffer.toString();
+    }
+
+    protected int getDataSize() {
+        return 4 // 2 short fields
+             + CellRangeAddress.ENCODED_SIZE
+             + field_4_cell_ranges.getSize();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_numcf);
+        out.writeShort(field_2_need_recalculation_and_id);
+        field_3_enclosing_cell_range.serialize(out);
+        field_4_cell_ranges.serialize(out);
+    }
+
+    protected void copyTo(CFHeaderBase result) {
+        result.field_1_numcf = field_1_numcf;
+        result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
+        result.field_3_enclosing_cell_range = field_3_enclosing_cell_range.copy();
+        result.field_4_cell_ranges = field_4_cell_ranges.copy();
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
index eb17ee2..a456224 100644
--- a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
+++ b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
@@ -17,144 +17,39 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.hssf.record.cf.CellRangeUtil;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.CellRangeAddressList;
-import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Conditional Formatting Header record CFHEADER (0x01B0)
- * 
- * @author Dmitriy Kumshayev
+ * Conditional Formatting Header record CFHEADER (0x01B0).
+ * Used to describe a {@link CFRuleRecord}.
+ * @see CFHeader12Record
  */
-public final class CFHeaderRecord extends StandardRecord {
-	public static final short sid = 0x01B0;
+public final class CFHeaderRecord extends CFHeaderBase {
+    public static final short sid = 0x01B0;
 
-	private int field_1_numcf;
-	private int field_2_need_recalculation;
-	private CellRangeAddress field_3_enclosing_cell_range;
-	private CellRangeAddressList field_4_cell_ranges;
+    /** Creates new CFHeaderRecord */
+    public CFHeaderRecord() {
+        createEmpty();
+    }
+    public CFHeaderRecord(CellRangeAddress[] regions, int nRules) {
+        super(regions, nRules);
+    }
 
-	/** Creates new CFHeaderRecord */
-	public CFHeaderRecord()
-	{
-		field_4_cell_ranges = new CellRangeAddressList();
-	}
-	public CFHeaderRecord(CellRangeAddress[] regions, int nRules) {
-		CellRangeAddress[] unmergedRanges = regions;
-		CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges);
-		setCellRanges(mergeCellRanges);
-		field_1_numcf = nRules;
-	}
+    public CFHeaderRecord(RecordInputStream in) {
+        read(in);
+    }
 
-	public CFHeaderRecord(RecordInputStream in)
-	{
-		field_1_numcf = in.readShort();
-		field_2_need_recalculation = in.readShort();
-		field_3_enclosing_cell_range = new CellRangeAddress(in);
-		field_4_cell_ranges = new CellRangeAddressList(in);
-	}
-	
-	public int getNumberOfConditionalFormats()
-	{
-		return field_1_numcf;
-	}
-	public void setNumberOfConditionalFormats(int n)
-	{
-		field_1_numcf=n;
-	}
-	
-	public boolean getNeedRecalculation()
-	{
-		return field_2_need_recalculation==1?true:false;
-	}
+    protected String getRecordName() {
+        return "CFHEADER";
+    }
 
-	public void setNeedRecalculation(boolean b)
-	{
-		field_2_need_recalculation=b?1:0;
-	}
-	
-	public CellRangeAddress getEnclosingCellRange()
-	{
-		return field_3_enclosing_cell_range;
-	}
+    public short getSid() {
+        return sid;
+    }
 
-	public void setEnclosingCellRange(CellRangeAddress cr)
-	{
-		field_3_enclosing_cell_range = cr;
-	}
-
-	/**
-	 * Set cell ranges list to a single cell range and 
-	 * modify the enclosing cell range accordingly.
-	 * @param cellRanges - list of CellRange objects
-	 */
-	public void setCellRanges(CellRangeAddress[] cellRanges)
-	{
-		if(cellRanges == null)
-		{
-			throw new IllegalArgumentException("cellRanges must not be null");
-		}
-		CellRangeAddressList cral = new CellRangeAddressList();
-		CellRangeAddress enclosingRange = null;
-		for (int i = 0; i < cellRanges.length; i++)
-		{
-			CellRangeAddress cr = cellRanges[i];
-			enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange);
-			cral.addCellRangeAddress(cr);
-		}
-		field_3_enclosing_cell_range = enclosingRange;
-		field_4_cell_ranges = cral;
-	}
-	
-	public CellRangeAddress[] getCellRanges() {
-		return field_4_cell_ranges.getCellRangeAddresses();
-	}
-
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-
-		buffer.append("[CFHEADER]\n");
-		buffer.append("	.id		= ").append(Integer.toHexString(sid)).append("\n");
-		buffer.append("	.numCF			= ").append(getNumberOfConditionalFormats()).append("\n");
-		buffer.append("	.needRecalc	   = ").append(getNeedRecalculation()).append("\n");
-		buffer.append("	.enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
-		buffer.append("	.cfranges=[");
-		for( int i=0; i<field_4_cell_ranges.countRanges(); i++)
-		{
-			buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
-		}
-		buffer.append("]\n");
-		buffer.append("[/CFHEADER]\n");
-		return buffer.toString();
-	}
-
-	protected int getDataSize() {
-		return 4 // 2 short fields
-			+ CellRangeAddress.ENCODED_SIZE
-			+ field_4_cell_ranges.getSize();
-	}
-	
-	public void serialize(LittleEndianOutput out) {
-
-		out.writeShort(field_1_numcf);
-		out.writeShort(field_2_need_recalculation);
-		field_3_enclosing_cell_range.serialize(out);
-		field_4_cell_ranges.serialize(out);
-	}
-
-	public short getSid() {
-		return sid;
-	}
-
-	public Object clone() 
-	{
-		CFHeaderRecord result = new CFHeaderRecord();
-		result.field_1_numcf = field_1_numcf;
-		result.field_2_need_recalculation = field_2_need_recalculation;
-		result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
-		result.field_4_cell_ranges = field_4_cell_ranges.copy();
-		return result;
-	}
+    public Object clone() {
+        CFHeaderRecord result = new CFHeaderRecord();
+        super.copyTo(result);
+        return result;
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/CFRule12Record.java b/src/java/org/apache/poi/hssf/record/CFRule12Record.java
new file mode 100644
index 0000000..c9d0f17
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/CFRule12Record.java
@@ -0,0 +1,365 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import java.util.Arrays;
+
+import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
+import org.apache.poi.hssf.record.cf.Threshold;
+import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.hssf.record.common.FutureRecord;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Conditional Formatting v12 Rule Record (0x087A). 
+ * 
+ * <p>This is for newer-style Excel conditional formattings,
+ *  from Excel 2007 onwards.
+ *  
+ * <p>{@link CFRuleRecord} is used where the condition type is
+ *  {@link #CONDITION_TYPE_CELL_VALUE_IS} or {@link #CONDITION_TYPE_FORMULA},
+ *  this is only used for the other types
+ */
+public final class CFRule12Record extends CFRuleBase implements FutureRecord {
+    public static final short sid = 0x087A;
+
+    private FtrHeader futureHeader;
+    private int ext_formatting_length;
+    private byte[] ext_formatting_data;
+    private Formula formula_scale;
+    private byte ext_opts;
+    private int priority;
+    private int template_type;
+    private byte template_param_length;
+    private byte[] template_params;
+    
+    private IconMultiStateFormatting multistate;
+    
+    // TODO Parse these
+    private byte[] gradient_data;
+    private byte[] databar_data;
+    private byte[] filter_data;
+
+    /** Creates new CFRuleRecord */
+    private CFRule12Record(byte conditionType, byte comparisonOperation) {
+        super(conditionType, comparisonOperation);
+        setDefaults();
+    }
+
+    private CFRule12Record(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2, Ptg[] formulaScale) {
+        super(conditionType, comparisonOperation, formula1, formula2);
+        setDefaults();
+        this.formula_scale = Formula.create(formulaScale);
+    }
+    private void setDefaults() {
+        futureHeader = new FtrHeader();
+        futureHeader.setRecordType(sid);
+        
+        ext_formatting_length = 0;
+        ext_formatting_data = new byte[4];
+        
+        formula_scale = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+        
+        ext_opts = 0;
+        priority = 0;
+        template_type = getConditionType();
+        template_param_length = 16;
+        template_params = new byte[template_param_length];
+    }
+
+    /**
+     * Creates a new comparison operation rule
+     */
+    public static CFRule12Record create(HSSFSheet sheet, String formulaText) {
+        Ptg[] formula1 = parseFormula(formulaText, sheet);
+        return new CFRule12Record(CONDITION_TYPE_FORMULA, ComparisonOperator.NO_COMPARISON,
+                formula1, null, null);
+    }
+    /**
+     * Creates a new comparison operation rule
+     */
+    public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation,
+            String formulaText1, String formulaText2) {
+        Ptg[] formula1 = parseFormula(formulaText1, sheet);
+        Ptg[] formula2 = parseFormula(formulaText2, sheet);
+        return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, 
+                formula1, formula2, null);
+    }
+    /**
+     * Creates a new comparison operation rule
+     */
+    public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation,
+            String formulaText1, String formulaText2, String formulaTextScale) {
+        Ptg[] formula1 = parseFormula(formulaText1, sheet);
+        Ptg[] formula2 = parseFormula(formulaText2, sheet);
+        Ptg[] formula3 = parseFormula(formulaTextScale, sheet);
+        return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, 
+                formula1, formula2, formula3);
+    }
+    /**
+     * Creates a new Icon Set / Multi-State formatting
+     */
+    public static CFRule12Record create(HSSFSheet sheet, IconSet iconSet) {
+        Threshold[] ts = new Threshold[iconSet.num];
+        for (int i=0; i<ts.length; i++) {
+            ts[i] = new Threshold();
+        }
+        
+        CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE, 
+                                              ComparisonOperator.NO_COMPARISON);
+        IconMultiStateFormatting imf = r.createMultiStateFormatting();
+        imf.setIconSet(iconSet);
+        imf.setThresholds(ts);
+        return r;
+    }
+    // TODO Static creators for the other record types
+
+    public CFRule12Record(RecordInputStream in) {
+        futureHeader = new FtrHeader(in);
+        setConditionType(in.readByte());
+        setComparisonOperation(in.readByte());
+        int field_3_formula1_len = in.readUShort();
+        int field_4_formula2_len = in.readUShort();
+        
+        ext_formatting_length = in.readInt();
+        ext_formatting_data = new byte[0];
+        if (ext_formatting_length == 0) {
+            // 2 bytes reserved
+            in.readUShort();
+        } else {
+            int len = readFormatOptions(in);
+            if (len < ext_formatting_length) {
+                ext_formatting_data = new byte[ext_formatting_length-len];
+                in.readFully(ext_formatting_data);
+            }
+        }
+        
+        setFormula1(Formula.read(field_3_formula1_len, in));
+        setFormula2(Formula.read(field_4_formula2_len, in));
+        
+        int formula_scale_len = in.readUShort();
+        formula_scale = Formula.read(formula_scale_len, in);
+        
+        ext_opts = in.readByte();
+        priority = in.readUShort();
+        template_type = in.readUShort();
+        template_param_length = in.readByte();
+        if (template_param_length == 0 || template_param_length == 16) {
+            template_params = new byte[template_param_length];
+            in.readFully(template_params);
+        } else {
+            logger.log(POILogger.WARN, "CF Rule v12 template params length should be 0 or 16, found " + template_param_length);
+            in.readRemainder();
+        }
+        
+        byte type = getConditionType();
+        if (type == CONDITION_TYPE_COLOR_SCALE) {
+            gradient_data = in.readRemainder();
+        } else if (type == CONDITION_TYPE_DATA_BAR) {
+            databar_data = in.readRemainder();
+        } else if (type == CONDITION_TYPE_FILTER) {
+            filter_data = in.readRemainder();
+        } else if (type == CONDITION_TYPE_ICON_SET) {
+            multistate = new IconMultiStateFormatting(in);
+        }
+    }
+    
+    public boolean containsMultiStateBlock() {
+        return (multistate != null);
+    }
+    public IconMultiStateFormatting getMultiStateFormatting() {
+        return multistate;
+    }
+    public IconMultiStateFormatting createMultiStateFormatting() {
+        if (multistate != null) return multistate;
+        
+        // Convert, setup and return
+        setConditionType(CONDITION_TYPE_ICON_SET);
+        multistate = new IconMultiStateFormatting();
+        return multistate;
+    }
+
+    /**
+     * get the stack of the scale expression as a list
+     *
+     * @return list of tokens (casts stack to a list and returns it!)
+     * this method can return null is we are unable to create Ptgs from
+     *	 existing excel file
+     * callers should check for null!
+     */
+    public Ptg[] getParsedExpressionScale() {
+        return formula_scale.getTokens();
+    }
+    public void setParsedExpressionScale(Ptg[] ptgs) {
+        formula_scale = Formula.create(ptgs);
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    /**
+     * called by the class that is responsible for writing this sucker.
+     * Subclasses should implement this so that their data is passed back in a
+     * byte array.
+     *
+     * @param out the stream to write to
+     */
+    public void serialize(LittleEndianOutput out) {
+        futureHeader.serialize(out);
+        
+        int formula1Len=getFormulaSize(getFormula1());
+        int formula2Len=getFormulaSize(getFormula2());
+
+        out.writeByte(getConditionType());
+        out.writeByte(getComparisonOperation());
+        out.writeShort(formula1Len);
+        out.writeShort(formula2Len);
+        
+        // TODO Update ext_formatting_length
+        if (ext_formatting_length == 0) {
+            out.writeInt(0);
+            out.writeShort(0);
+        } else {
+            out.writeInt(ext_formatting_length);
+            serializeFormattingBlock(out);
+            out.write(ext_formatting_data);
+        }
+        
+        getFormula1().serializeTokens(out);
+        getFormula2().serializeTokens(out);
+        out.writeShort(getFormulaSize(formula_scale));
+        formula_scale.serializeTokens(out);
+        
+        out.writeByte(ext_opts);
+        out.writeShort(priority);
+        out.writeShort(template_type);
+        out.writeByte(template_param_length);
+        out.write(template_params);
+        
+        byte type = getConditionType();
+        if (type == CONDITION_TYPE_COLOR_SCALE) {
+            out.write(gradient_data);
+        } else if (type == CONDITION_TYPE_DATA_BAR) {
+            out.write(databar_data);
+        } else if (type == CONDITION_TYPE_FILTER) {
+            out.write(filter_data);
+        } else if (type == CONDITION_TYPE_ICON_SET) {
+            multistate.serialize(out);
+        }
+    }
+
+    protected int getDataSize() {
+        int len = FtrHeader.getDataSize() + 6;
+        if (ext_formatting_length == 0) {
+            len += 6;
+        } else {
+            len += 4 + getFormattingBlockSize() + ext_formatting_data.length;
+        }
+        len += getFormulaSize(getFormula1());
+        len += getFormulaSize(getFormula2());
+        len += 2 + getFormulaSize(formula_scale);
+        len += 6 + template_params.length;
+        
+        byte type = getConditionType();
+        if (type == CONDITION_TYPE_COLOR_SCALE) {
+            len += gradient_data.length;
+        } else if (type == CONDITION_TYPE_DATA_BAR) {
+            len += databar_data.length;
+        } else if (type == CONDITION_TYPE_FILTER) {
+            len += filter_data.length;
+        } else if (type == CONDITION_TYPE_ICON_SET) {
+            len += multistate.getDataLength();
+        }
+        return len;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("[CFRULE12]\n");
+        buffer.append("    .condition_type=").append(getConditionType()).append("\n");
+        buffer.append("    .dxfn12_length =0x").append(Integer.toHexString(ext_formatting_length)).append("\n");
+        buffer.append("    .option_flags  =0x").append(Integer.toHexString(getOptions())).append("\n");
+        if (containsFontFormattingBlock()) {
+            buffer.append(_fontFormatting.toString()).append("\n");
+        }
+        if (containsBorderFormattingBlock()) {
+            buffer.append(_borderFormatting.toString()).append("\n");
+        }
+        if (containsPatternFormattingBlock()) {
+            buffer.append(_patternFormatting.toString()).append("\n");
+        }
+        buffer.append("    .dxfn12_ext=").append(HexDump.toHex(ext_formatting_data)).append("\n");
+        buffer.append("    .formula_1 =").append(Arrays.toString(getFormula1().getTokens())).append("\n");
+        buffer.append("    .formula_2 =").append(Arrays.toString(getFormula2().getTokens())).append("\n");
+        buffer.append("    .formula_S =").append(Arrays.toString(formula_scale.getTokens())).append("\n");
+        buffer.append("    .ext_opts  =").append(ext_opts).append("\n");
+        buffer.append("    .priority  =").append(priority).append("\n");
+        buffer.append("    .template_type  =").append(template_type).append("\n");
+        buffer.append("    .template_params=").append(HexDump.toHex(template_params)).append("\n");
+        buffer.append("    .gradient_data  =").append(HexDump.toHex(gradient_data)).append("\n");
+        buffer.append("    .databar_data   =").append(HexDump.toHex(databar_data)).append("\n");
+        buffer.append("    .filter_data    =").append(HexDump.toHex(filter_data)).append("\n");
+        if (multistate != null) {
+            buffer.append(multistate);
+        }
+        buffer.append("[/CFRULE12]\n");
+        return buffer.toString();
+    }
+
+    public Object clone() {
+        CFRule12Record rec = new CFRule12Record(getConditionType(), getComparisonOperation());
+        rec.futureHeader.setAssociatedRange(futureHeader.getAssociatedRange().copy());
+        
+        super.copyTo(rec);
+        
+        rec.ext_formatting_length = ext_formatting_length;
+        rec.ext_formatting_data = new byte[ext_formatting_length];
+        System.arraycopy(ext_formatting_data, 0, rec.ext_formatting_data, 0, ext_formatting_length);
+        
+        rec.formula_scale = formula_scale.copy();
+        
+        rec.ext_opts = ext_opts;
+        rec.priority = priority;
+        rec.template_type = template_type;
+        rec.template_param_length = template_param_length;
+        rec.template_params = new byte[template_param_length];
+        System.arraycopy(template_params, 0, rec.template_params, 0, template_param_length);
+
+        // TODO Clone the rgbCT data like Gradients, Databars etc
+        
+        return rec;
+    }
+    
+    public short getFutureRecordType() {
+        return futureHeader.getRecordType();
+    }
+    public FtrHeader getFutureHeader() {
+        return futureHeader;
+    }
+    public CellRangeAddress getAssociatedRange() {
+        return futureHeader.getAssociatedRange();
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/CFRuleBase.java b/src/java/org/apache/poi/hssf/record/CFRuleBase.java
new file mode 100644
index 0000000..7dfcc37
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/CFRuleBase.java
@@ -0,0 +1,455 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.record.cf.BorderFormatting;
+import org.apache.poi.hssf.record.cf.FontFormatting;
+import org.apache.poi.hssf.record.cf.PatternFormatting;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Conditional Formatting Rules. This can hold old-style rules
+ *   
+ * 
+ * <p>This is for the older-style Excel conditional formattings,
+ *  new-style (Excel 2007+) also make use of {@link CFRule12Record}
+ *  and {@link CFExRuleRecord} for their rules.
+ */
+public abstract class CFRuleBase extends StandardRecord {
+    public static final class ComparisonOperator {
+        public static final byte NO_COMPARISON = 0;
+        public static final byte BETWEEN       = 1;
+        public static final byte NOT_BETWEEN   = 2;
+        public static final byte EQUAL         = 3;
+        public static final byte NOT_EQUAL     = 4;
+        public static final byte GT            = 5;
+        public static final byte LT            = 6;
+        public static final byte GE            = 7;
+        public static final byte LE            = 8;
+        private static final byte max_operator = 8;
+    }
+    protected static final POILogger logger = POILogFactory.getLogger(CFRuleBase.class);
+
+    private byte condition_type;
+    // The only kinds that CFRuleRecord handles
+    public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;
+    public static final byte CONDITION_TYPE_FORMULA = 2;
+    // These are CFRule12Rule only
+    public static final byte CONDITION_TYPE_COLOR_SCALE = 3;
+    public static final byte CONDITION_TYPE_DATA_BAR = 4;
+    public static final byte CONDITION_TYPE_FILTER = 5;
+    public static final byte CONDITION_TYPE_ICON_SET = 6;
+
+    private byte comparison_operator;
+
+    public static final int TEMPLATE_CELL_VALUE = 0x0000;
+    public static final int TEMPLATE_FORMULA = 0x0001;
+    public static final int TEMPLATE_COLOR_SCALE_FORMATTING = 0x0002;
+    public static final int TEMPLATE_DATA_BAR_FORMATTING = 0x0003;
+    public static final int TEMPLATE_ICON_SET_FORMATTING = 0x0004;
+    public static final int TEMPLATE_FILTER = 0x0005;
+    public static final int TEMPLATE_UNIQUE_VALUES = 0x0007;
+    public static final int TEMPLATE_CONTAINS_TEXT = 0x0008;
+    public static final int TEMPLATE_CONTAINS_BLANKS = 0x0009;
+    public static final int TEMPLATE_CONTAINS_NO_BLANKS = 0x000A;
+    public static final int TEMPLATE_CONTAINS_ERRORS = 0x000B;
+    public static final int TEMPLATE_CONTAINS_NO_ERRORS = 0x000C;
+    public static final int TEMPLATE_TODAY = 0x000F;
+    public static final int TEMPLATE_TOMORROW = 0x0010;
+    public static final int TEMPLATE_YESTERDAY = 0x0011;
+    public static final int TEMPLATE_LAST_7_DAYS = 0x0012;
+    public static final int TEMPLATE_LAST_MONTH = 0x0013;
+    public static final int TEMPLATE_NEXT_MONTH = 0x0014;
+    public static final int TEMPLATE_THIS_WEEK = 0x0015;
+    public static final int TEMPLATE_NEXT_WEEK = 0x0016;
+    public static final int TEMPLATE_LAST_WEEK = 0x0017;
+    public static final int TEMPLATE_THIS_MONTH = 0x0018;
+    public static final int TEMPLATE_ABOVE_AVERAGE = 0x0019;
+    public static final int TEMPLATE_BELOW_AVERAGE = 0x001A;
+    public static final int TEMPLATE_DUPLICATE_VALUES = 0x001B;
+    public static final int TEMPLATE_ABOVE_OR_EQUAL_TO_AVERAGE = 0x001D;
+    public static final int TEMPLATE_BELOW_OR_EQUAL_TO_AVERAGE = 0x001E;
+    
+    static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
+    static final BitField alignHor         = bf(0x00000001); // 0 = Horizontal alignment modified
+    static final BitField alignVer         = bf(0x00000002); // 0 = Vertical alignment modified
+    static final BitField alignWrap        = bf(0x00000004); // 0 = Text wrapped flag modified
+    static final BitField alignRot         = bf(0x00000008); // 0 = Text rotation modified
+    static final BitField alignJustLast    = bf(0x00000010); // 0 = Justify last line flag modified
+    static final BitField alignIndent      = bf(0x00000020); // 0 = Indentation modified
+    static final BitField alignShrin       = bf(0x00000040); // 0 = Shrink to fit flag modified
+    static final BitField mergeCell        = bf(0x00000080); // Normally 1, 0 = Merge Cell flag modified
+    static final BitField protLocked       = bf(0x00000100); // 0 = Cell locked flag modified
+    static final BitField protHidden       = bf(0x00000200); // 0 = Cell hidden flag modified
+    static final BitField bordLeft         = bf(0x00000400); // 0 = Left border style and colour modified
+    static final BitField bordRight        = bf(0x00000800); // 0 = Right border style and colour modified
+    static final BitField bordTop          = bf(0x00001000); // 0 = Top border style and colour modified
+    static final BitField bordBot          = bf(0x00002000); // 0 = Bottom border style and colour modified
+    static final BitField bordTlBr         = bf(0x00004000); // 0 = Top-left to bottom-right border flag modified
+    static final BitField bordBlTr         = bf(0x00008000); // 0 = Bottom-left to top-right border flag modified
+    static final BitField pattStyle        = bf(0x00010000); // 0 = Pattern style modified
+    static final BitField pattCol          = bf(0x00020000); // 0 = Pattern colour modified
+    static final BitField pattBgCol        = bf(0x00040000); // 0 = Pattern background colour modified
+    static final BitField notUsed2         = bf(0x00380000); // Always 111 (ifmt / ifnt / 1)
+    static final BitField undocumented     = bf(0x03C00000); // Undocumented bits
+    static final BitField fmtBlockBits     = bf(0x7C000000); // Bits: font,align,bord,patt,prot
+    static final BitField font             = bf(0x04000000); // 1 = Record contains font formatting block
+    static final BitField align            = bf(0x08000000); // 1 = Record contains alignment formatting block
+    static final BitField bord             = bf(0x10000000); // 1 = Record contains border formatting block
+    static final BitField patt             = bf(0x20000000); // 1 = Record contains pattern formatting block
+    static final BitField prot             = bf(0x40000000); // 1 = Record contains protection formatting block
+    static final BitField alignTextDir     = bf(0x80000000); // 0 = Text direction modified
+
+    private static BitField bf(int i) {
+        return BitFieldFactory.getInstance(i);
+    }
+
+    protected int formatting_options;
+    protected short formatting_not_used; // TODO Decode this properly
+
+    protected FontFormatting _fontFormatting;
+    protected BorderFormatting _borderFormatting;
+    protected PatternFormatting _patternFormatting;
+    
+    private Formula formula1;
+    private Formula formula2;
+
+    /** Creates new CFRuleRecord */
+    protected CFRuleBase(byte conditionType, byte comparisonOperation) {
+        setConditionType(conditionType);
+        setComparisonOperation(comparisonOperation);
+        formula1 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+        formula2 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+    }
+    protected CFRuleBase(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) {
+        this(conditionType, comparisonOperation);
+        this.formula1 = Formula.create(formula1);
+        this.formula2 = Formula.create(formula2);
+    }
+    protected CFRuleBase() {}
+    
+    protected int readFormatOptions(RecordInputStream in) {
+        formatting_options = in.readInt();
+        formatting_not_used = in.readShort();
+
+        int len = 6;
+        
+        if (containsFontFormattingBlock()) {
+            _fontFormatting = new FontFormatting(in);
+            len += _fontFormatting.getDataLength();
+        }
+
+        if (containsBorderFormattingBlock()) {
+            _borderFormatting = new BorderFormatting(in);
+            len += _borderFormatting.getDataLength();
+        }
+
+        if (containsPatternFormattingBlock()) {
+            _patternFormatting = new PatternFormatting(in);
+            len += _patternFormatting.getDataLength();
+        }
+        
+        return len;
+    }
+
+    public byte getConditionType() {
+        return condition_type;
+    }
+    protected void setConditionType(byte condition_type) {
+        if ((this instanceof CFRuleRecord)) {
+            if (condition_type == CONDITION_TYPE_CELL_VALUE_IS ||
+                condition_type == CONDITION_TYPE_FORMULA) {
+                // Good, valid combination
+            } else {
+                throw new IllegalArgumentException("CFRuleRecord only accepts Value-Is and Formula types");
+            }
+        }
+        this.condition_type = condition_type;
+    }
+
+    public void setComparisonOperation(byte operation) {
+        if (operation < 0 || operation > ComparisonOperator.max_operator)
+            throw new IllegalArgumentException(
+                    "Valid operators are only in the range 0 to " +ComparisonOperator.max_operator);
+        
+        this.comparison_operator = operation;
+    }
+    public byte getComparisonOperation() {
+        return comparison_operator;
+    }
+
+    public boolean containsFontFormattingBlock() {
+        return getOptionFlag(font);
+    }
+    public void setFontFormatting(FontFormatting fontFormatting) {
+        _fontFormatting = fontFormatting;
+        setOptionFlag(fontFormatting != null, font);
+    }
+    public FontFormatting getFontFormatting() {
+        if( containsFontFormattingBlock()) {
+            return _fontFormatting;
+        }
+        return null;
+    }
+
+    public boolean containsAlignFormattingBlock() {
+        return getOptionFlag(align);
+    }
+    public void setAlignFormattingUnchanged() {
+        setOptionFlag(false,align);
+    }
+
+    public boolean containsBorderFormattingBlock() {
+        return getOptionFlag(bord);
+    }
+    public void setBorderFormatting(BorderFormatting borderFormatting) {
+        _borderFormatting = borderFormatting;
+        setOptionFlag(borderFormatting != null, bord);
+    }
+    public BorderFormatting getBorderFormatting() {
+        if( containsBorderFormattingBlock()) {
+            return _borderFormatting;
+        }
+        return null;
+    }
+
+    public boolean containsPatternFormattingBlock() {
+        return getOptionFlag(patt);
+    }
+    public void setPatternFormatting(PatternFormatting patternFormatting) {
+        _patternFormatting = patternFormatting;
+        setOptionFlag(patternFormatting!=null, patt);
+    }
+    public PatternFormatting getPatternFormatting() {
+        if( containsPatternFormattingBlock())
+        {
+            return _patternFormatting;
+        }
+        return null;
+    }
+
+    public boolean containsProtectionFormattingBlock() {
+        return getOptionFlag(prot);
+    }
+    public void setProtectionFormattingUnchanged() {
+        setOptionFlag(false,prot);
+    }
+
+    /**
+     * get the option flags
+     *
+     * @return bit mask
+     */
+    public int getOptions() {
+        return formatting_options;
+    }
+
+    private boolean isModified(BitField field) {
+        return !field.isSet(formatting_options);
+    }
+    private void setModified(boolean modified, BitField field) {
+        formatting_options = field.setBoolean(formatting_options, !modified);
+    }
+
+    public boolean isLeftBorderModified() {
+        return isModified(bordLeft);
+    }
+    public void setLeftBorderModified(boolean modified) {
+        setModified(modified,bordLeft);
+    }
+
+    public boolean isRightBorderModified() {
+        return isModified(bordRight);
+    }
+    public void setRightBorderModified(boolean modified)
+    {
+        setModified(modified,bordRight);
+    }
+
+    public boolean isTopBorderModified() {
+        return isModified(bordTop);
+    }
+    public void setTopBorderModified(boolean modified) {
+        setModified(modified,bordTop);
+    }
+
+    public boolean isBottomBorderModified() {
+        return isModified(bordBot);
+    }
+    public void setBottomBorderModified(boolean modified) {
+        setModified(modified,bordBot);
+    }
+
+    public boolean isTopLeftBottomRightBorderModified() {
+        return isModified(bordTlBr);
+    }
+    public void setTopLeftBottomRightBorderModified(boolean modified) {
+        setModified(modified,bordTlBr);
+    }
+
+    public boolean isBottomLeftTopRightBorderModified() {
+        return isModified(bordBlTr);
+    }
+    public void setBottomLeftTopRightBorderModified(boolean modified) {
+        setModified(modified,bordBlTr);
+    }
+
+    public boolean isPatternStyleModified() {
+        return isModified(pattStyle);
+    }
+    public void setPatternStyleModified(boolean modified) {
+        setModified(modified,pattStyle);
+    }
+
+    public boolean isPatternColorModified() {
+        return isModified(pattCol);
+    }
+    public void setPatternColorModified(boolean modified) {
+        setModified(modified,pattCol);
+    }
+
+    public boolean isPatternBackgroundColorModified() {
+        return isModified(pattBgCol);
+    }
+    public void setPatternBackgroundColorModified(boolean modified) {
+        setModified(modified,pattBgCol);
+    }
+
+    private boolean getOptionFlag(BitField field) {
+        return field.isSet(formatting_options);
+    }
+    private void setOptionFlag(boolean flag, BitField field) {
+        formatting_options = field.setBoolean(formatting_options, flag);
+    }
+    
+    protected int getFormattingBlockSize() {
+        return 6 +
+          (containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+
+          (containsBorderFormattingBlock()?8:0)+
+          (containsPatternFormattingBlock()?4:0);
+    }
+    protected void serializeFormattingBlock(LittleEndianOutput out) {
+        out.writeInt(formatting_options);
+        out.writeShort(formatting_not_used);
+
+        if (containsFontFormattingBlock()) {
+            byte[] fontFormattingRawRecord  = _fontFormatting.getRawRecord();
+            out.write(fontFormattingRawRecord);
+        }
+
+        if (containsBorderFormattingBlock()) {
+            _borderFormatting.serialize(out);
+        }
+
+        if (containsPatternFormattingBlock()) {
+            _patternFormatting.serialize(out);
+        }
+    }
+    
+    /**
+     * get the stack of the 1st expression as a list
+     *
+     * @return list of tokens (casts stack to a list and returns it!)
+     * this method can return null is we are unable to create Ptgs from
+     *	 existing excel file
+     * callers should check for null!
+     */
+    public Ptg[] getParsedExpression1() {
+        return formula1.getTokens();
+    }
+    public void setParsedExpression1(Ptg[] ptgs) {
+        formula1 = Formula.create(ptgs);
+    }
+    protected Formula getFormula1() {
+        return formula1;
+    }
+    protected void setFormula1(Formula formula1) {
+        this.formula1 = formula1;
+    }
+
+    /**
+     * get the stack of the 2nd expression as a list
+     *
+     * @return array of {@link Ptg}s, possibly <code>null</code>
+     */
+    public Ptg[] getParsedExpression2() {
+        return Formula.getTokens(formula2);
+    }
+    public void setParsedExpression2(Ptg[] ptgs) {
+        formula2 = Formula.create(ptgs);
+    }
+    protected Formula getFormula2() {
+        return formula2;
+    }
+    protected void setFormula2(Formula formula2) {
+        this.formula2 = formula2;
+    }
+
+    /**
+     * @param formula must not be <code>null</code>
+     * @return encoded size of the formula tokens (does not include 2 bytes for ushort length)
+     */
+    protected static int getFormulaSize(Formula formula) {
+        return formula.getEncodedTokenSize();
+    }
+
+    /**
+     * TODO - parse conditional format formulas properly i.e. produce tRefN and tAreaN instead of tRef and tArea
+     * this call will produce the wrong results if the formula contains any cell references
+     * One approach might be to apply the inverse of SharedFormulaRecord.convertSharedFormulas(Stack, int, int)
+     * Note - two extra parameters (rowIx & colIx) will be required. They probably come from one of the Region objects.
+     *
+     * @return <code>null</code> if <tt>formula</tt> was null.
+     */
+    public static Ptg[] parseFormula(String formula, HSSFSheet sheet) {
+        if(formula == null) {
+            return null;
+        }
+        int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
+        return HSSFFormulaParser.parse(formula, sheet.getWorkbook(), FormulaType.CELL, sheetIndex);
+    }
+    
+    protected void copyTo(CFRuleBase rec) {
+        rec.condition_type = condition_type;
+        rec.comparison_operator = comparison_operator;
+        
+        rec.formatting_options = formatting_options;
+        rec.formatting_not_used = formatting_not_used;
+        if (containsFontFormattingBlock()) {
+            rec._fontFormatting = (FontFormatting) _fontFormatting.clone();
+        }
+        if (containsBorderFormattingBlock()) {
+            rec._borderFormatting = (BorderFormatting) _borderFormatting.clone();
+        }
+        if (containsPatternFormattingBlock()) {
+            rec._patternFormatting = (PatternFormatting) _patternFormatting.clone();
+        }
+        
+        rec.setFormula1(getFormula1().copy());
+        rec.setFormula2(getFormula2().copy());
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java
index 4cf83ef..52678c0 100644
--- a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java
+++ b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java
@@ -19,512 +19,129 @@
 
 import java.util.Arrays;
 
-import org.apache.poi.hssf.model.HSSFFormulaParser;
-import org.apache.poi.hssf.record.cf.BorderFormatting;
-import org.apache.poi.hssf.record.cf.FontFormatting;
-import org.apache.poi.hssf.record.cf.PatternFormatting;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.ss.formula.Formula;
-import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.formula.ptg.Ptg;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Conditional Formatting Rule Record (0x01B1).<br/>
- *
- * @author Dmitriy Kumshayev
+ * Conditional Formatting Rule Record (0x01B1). 
+ * 
+ * <p>This is for the older-style Excel conditional formattings,
+ *  new-style (Excel 2007+) also make use of {@link CFRule12Record}
+ *  and {@link CFExRuleRecord} for their rules.
  */
-public final class CFRuleRecord extends StandardRecord {
+public final class CFRuleRecord extends CFRuleBase {
+    public static final short sid = 0x01B1;
 
-	public static final short sid = 0x01B1;
+    /** Creates new CFRuleRecord */
+    private CFRuleRecord(byte conditionType, byte comparisonOperation) {
+        super(conditionType, comparisonOperation);
+        setDefaults();
+    }
 
-	public static final class ComparisonOperator {
-		public static final byte NO_COMPARISON = 0;
-		public static final byte BETWEEN       = 1;
-		public static final byte NOT_BETWEEN   = 2;
-		public static final byte EQUAL         = 3;
-		public static final byte NOT_EQUAL     = 4;
-		public static final byte GT            = 5;
-		public static final byte LT            = 6;
-		public static final byte GE            = 7;
-		public static final byte LE            = 8;
-	}
+    private CFRuleRecord(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) {
+        super(conditionType, comparisonOperation, formula1, formula2);
+        setDefaults();
+    }
+    private void setDefaults() {
+        // Set modification flags to 1: by default options are not modified
+        formatting_options = modificationBits.setValue(formatting_options, -1);
+        // Set formatting block flags to 0 (no formatting blocks)
+        formatting_options = fmtBlockBits.setValue(formatting_options, 0);
+        formatting_options = undocumented.clear(formatting_options);
 
-	private byte  field_1_condition_type;
-	public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;
-	public static final byte CONDITION_TYPE_FORMULA = 2;
+        formatting_not_used = (short)0x8002; // Excel seems to write this value, but it doesn't seem to care what it reads
+        _fontFormatting = null;
+        _borderFormatting = null;
+        _patternFormatting = null;
+    }
 
-	private byte  field_2_comparison_operator;
-
-	private int   field_5_options;
-
-	private static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
-	private static final BitField alignHor      = bf(0x00000001); // 0 = Horizontal alignment modified
-	private static final BitField alignVer      = bf(0x00000002); // 0 = Vertical alignment modified
-	private static final BitField alignWrap     = bf(0x00000004); // 0 = Text wrapped flag modified
-	private static final BitField alignRot      = bf(0x00000008); // 0 = Text rotation modified
-	private static final BitField alignJustLast = bf(0x00000010); // 0 = Justify last line flag modified
-	private static final BitField alignIndent   = bf(0x00000020); // 0 = Indentation modified
-	private static final BitField alignShrin    = bf(0x00000040); // 0 = Shrink to fit flag modified
-	private static final BitField notUsed1      = bf(0x00000080); // Always 1
-	private static final BitField protLocked    = bf(0x00000100); // 0 = Cell locked flag modified
-	private static final BitField protHidden    = bf(0x00000200); // 0 = Cell hidden flag modified
-	private static final BitField bordLeft      = bf(0x00000400); // 0 = Left border style and colour modified
-	private static final BitField bordRight     = bf(0x00000800); // 0 = Right border style and colour modified
-	private static final BitField bordTop       = bf(0x00001000); // 0 = Top border style and colour modified
-	private static final BitField bordBot       = bf(0x00002000); // 0 = Bottom border style and colour modified
-	private static final BitField bordTlBr      = bf(0x00004000); // 0 = Top-left to bottom-right border flag modified
-	private static final BitField bordBlTr      = bf(0x00008000); // 0 = Bottom-left to top-right border flag modified
-	private static final BitField pattStyle     = bf(0x00010000); // 0 = Pattern style modified
-	private static final BitField pattCol       = bf(0x00020000); // 0 = Pattern colour modified
-	private static final BitField pattBgCol     = bf(0x00040000); // 0 = Pattern background colour modified
-	private static final BitField notUsed2      = bf(0x00380000); // Always 111
-	private static final BitField undocumented  = bf(0x03C00000); // Undocumented bits
-	private static final BitField fmtBlockBits  = bf(0x7C000000); // Bits: font,align,bord,patt,prot
-	private static final BitField font          = bf(0x04000000); // 1 = Record contains font formatting block
-	private static final BitField align         = bf(0x08000000); // 1 = Record contains alignment formatting block
-	private static final BitField bord          = bf(0x10000000); // 1 = Record contains border formatting block
-	private static final BitField patt          = bf(0x20000000); // 1 = Record contains pattern formatting block
-	private static final BitField prot          = bf(0x40000000); // 1 = Record contains protection formatting block
-	private static final BitField alignTextDir  = bf(0x80000000); // 0 = Text direction modified
-
-
-	private static BitField bf(int i) {
-		return BitFieldFactory.getInstance(i);
-	}
-
-	private short field_6_not_used;
-
-	private FontFormatting _fontFormatting;
-
-	private BorderFormatting _borderFormatting;
-
-	private PatternFormatting _patternFormatting;
-
-	private Formula field_17_formula1;
-	private Formula field_18_formula2;
-
-	/** Creates new CFRuleRecord */
-	private CFRuleRecord(byte conditionType, byte comparisonOperation)
-	{
-		field_1_condition_type=conditionType;
-		field_2_comparison_operator=comparisonOperation;
-
-		// Set modification flags to 1: by default options are not modified
-		field_5_options = modificationBits.setValue(field_5_options, -1);
-		// Set formatting block flags to 0 (no formatting blocks)
-		field_5_options = fmtBlockBits.setValue(field_5_options, 0);
-		field_5_options = undocumented.clear(field_5_options);
-
-		field_6_not_used = (short)0x8002; // Excel seems to write this value, but it doesn't seem to care what it reads
-		_fontFormatting=null;
-		_borderFormatting=null;
-		_patternFormatting=null;
-		field_17_formula1=Formula.create(Ptg.EMPTY_PTG_ARRAY);
-		field_18_formula2=Formula.create(Ptg.EMPTY_PTG_ARRAY);
-	}
-
-	private CFRuleRecord(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) {
-		this(conditionType, comparisonOperation);
-		field_17_formula1 = Formula.create(formula1);
-		field_18_formula2 = Formula.create(formula2);
-	}
-
-	/**
-	 * Creates a new comparison operation rule
-	 */
+    /**
+     * Creates a new comparison operation rule
+     */
     public static CFRuleRecord create(HSSFSheet sheet, String formulaText) {
         Ptg[] formula1 = parseFormula(formulaText, sheet);
         return new CFRuleRecord(CONDITION_TYPE_FORMULA, ComparisonOperator.NO_COMPARISON,
                 formula1, null);
     }
-	/**
-	 * Creates a new comparison operation rule
-	 */
-	public static CFRuleRecord create(HSSFSheet sheet, byte comparisonOperation,
-			String formulaText1, String formulaText2) {
-		Ptg[] formula1 = parseFormula(formulaText1, sheet);
-		Ptg[] formula2 = parseFormula(formulaText2, sheet);
-		return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2);
-	}
+    /**
+     * Creates a new comparison operation rule
+     */
+    public static CFRuleRecord create(HSSFSheet sheet, byte comparisonOperation,
+            String formulaText1, String formulaText2) {
+        Ptg[] formula1 = parseFormula(formulaText1, sheet);
+        Ptg[] formula2 = parseFormula(formulaText2, sheet);
+        return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2);
+    }
 
-	public CFRuleRecord(RecordInputStream in) {
-		field_1_condition_type = in.readByte();
-		field_2_comparison_operator = in.readByte();
-		int field_3_formula1_len = in.readUShort();
-		int field_4_formula2_len = in.readUShort();
-		field_5_options = in.readInt();
-		field_6_not_used = in.readShort();
+    public CFRuleRecord(RecordInputStream in) {
+        setConditionType(in.readByte());
+        setComparisonOperation(in.readByte());
+        int field_3_formula1_len = in.readUShort();
+        int field_4_formula2_len = in.readUShort();
+        readFormatOptions(in);
 
-		if (containsFontFormattingBlock()) {
-			_fontFormatting = new FontFormatting(in);
-		}
+        // "You may not use unions, intersections or array constants in Conditional Formatting criteria"
+        setFormula1(Formula.read(field_3_formula1_len, in));
+        setFormula2(Formula.read(field_4_formula2_len, in));
+    }
 
-		if (containsBorderFormattingBlock()) {
-			_borderFormatting = new BorderFormatting(in);
-		}
+    public short getSid() {
+        return sid;
+    }
 
-		if (containsPatternFormattingBlock()) {
-			_patternFormatting = new PatternFormatting(in);
-		}
+    /**
+     * called by the class that is responsible for writing this sucker.
+     * Subclasses should implement this so that their data is passed back in a
+     * byte array.
+     *
+     * @param out the stream to write to
+     */
+    public void serialize(LittleEndianOutput out) {
+        int formula1Len=getFormulaSize(getFormula1());
+        int formula2Len=getFormulaSize(getFormula2());
 
-		// "You may not use unions, intersections or array constants in Conditional Formatting criteria"
-		field_17_formula1 = Formula.read(field_3_formula1_len, in);
-		field_18_formula2 = Formula.read(field_4_formula2_len, in);
-	}
+        out.writeByte(getConditionType());
+        out.writeByte(getComparisonOperation());
+        out.writeShort(formula1Len);
+        out.writeShort(formula2Len);
+        
+        serializeFormattingBlock(out);
 
-	public byte getConditionType()
-	{
-		return field_1_condition_type;
-	}
+        getFormula1().serializeTokens(out);
+        getFormula2().serializeTokens(out);
+    }
 
-	public boolean containsFontFormattingBlock()
-	{
-		return getOptionFlag(font);
-	}
-	public void setFontFormatting(FontFormatting fontFormatting)
-	{
-		_fontFormatting = fontFormatting;
-		setOptionFlag(fontFormatting != null, font);
-	}
-	public FontFormatting getFontFormatting()
-	{
-		if( containsFontFormattingBlock())
-		{
-			return _fontFormatting;
-		}
-		return null;
-	}
+    protected int getDataSize() {
+        return 6 + getFormattingBlockSize() +
+               getFormulaSize(getFormula1())+
+               getFormulaSize(getFormula2());
+    }
 
-	public boolean containsAlignFormattingBlock()
-	{
-		return getOptionFlag(align);
-	}
-	public void setAlignFormattingUnchanged()
-	{
-		setOptionFlag(false,align);
-	}
-
-	public boolean containsBorderFormattingBlock()
-	{
-		return getOptionFlag(bord);
-	}
-	public void setBorderFormatting(BorderFormatting borderFormatting)
-	{
-		_borderFormatting = borderFormatting;
-		setOptionFlag(borderFormatting != null, bord);
-	}
-	public BorderFormatting getBorderFormatting()
-	{
-		if( containsBorderFormattingBlock())
-		{
-			return _borderFormatting;
-		}
-		return null;
-	}
-
-	public boolean containsPatternFormattingBlock()
-	{
-		return getOptionFlag(patt);
-	}
-	public void setPatternFormatting(PatternFormatting patternFormatting)
-	{
-		_patternFormatting = patternFormatting;
-		setOptionFlag(patternFormatting!=null, patt);
-	}
-	public PatternFormatting getPatternFormatting()
-	{
-		if( containsPatternFormattingBlock())
-		{
-			return _patternFormatting;
-		}
-		return null;
-	}
-
-	public boolean containsProtectionFormattingBlock()
-	{
-		return getOptionFlag(prot);
-	}
-	public void setProtectionFormattingUnchanged()
-	{
-		setOptionFlag(false,prot);
-	}
-
-	public void setComparisonOperation(byte operation)
-	{
-		field_2_comparison_operator = operation;
-	}
-
-	public byte getComparisonOperation()
-	{
-		return field_2_comparison_operator;
-	}
-
-
-	/**
-	 * get the option flags
-	 *
-	 * @return bit mask
-	 */
-	public int getOptions()
-	{
-		return field_5_options;
-	}
-
-	private boolean isModified(BitField field)
-	{
-		return !field.isSet(field_5_options);
-	}
-
-	private void setModified(boolean modified, BitField field)
-	{
-		field_5_options = field.setBoolean(field_5_options, !modified);
-	}
-
-	public boolean isLeftBorderModified()
-	{
-		return isModified(bordLeft);
-	}
-
-	public void setLeftBorderModified(boolean modified)
-	{
-		setModified(modified,bordLeft);
-	}
-
-	public boolean isRightBorderModified()
-	{
-		return isModified(bordRight);
-	}
-
-	public void setRightBorderModified(boolean modified)
-	{
-		setModified(modified,bordRight);
-	}
-
-	public boolean isTopBorderModified()
-	{
-		return isModified(bordTop);
-	}
-
-	public void setTopBorderModified(boolean modified)
-	{
-		setModified(modified,bordTop);
-	}
-
-	public boolean isBottomBorderModified()
-	{
-		return isModified(bordBot);
-	}
-
-	public void setBottomBorderModified(boolean modified)
-	{
-		setModified(modified,bordBot);
-	}
-
-	public boolean isTopLeftBottomRightBorderModified()
-	{
-		return isModified(bordTlBr);
-	}
-
-	public void setTopLeftBottomRightBorderModified(boolean modified)
-	{
-		setModified(modified,bordTlBr);
-	}
-
-	public boolean isBottomLeftTopRightBorderModified()
-	{
-		return isModified(bordBlTr);
-	}
-
-	public void setBottomLeftTopRightBorderModified(boolean modified)
-	{
-		setModified(modified,bordBlTr);
-	}
-
-	public boolean isPatternStyleModified()
-	{
-		return isModified(pattStyle);
-	}
-
-	public void setPatternStyleModified(boolean modified)
-	{
-		setModified(modified,pattStyle);
-	}
-
-	public boolean isPatternColorModified()
-	{
-		return isModified(pattCol);
-	}
-
-	public void setPatternColorModified(boolean modified)
-	{
-		setModified(modified,pattCol);
-	}
-
-	public boolean isPatternBackgroundColorModified()
-	{
-		return isModified(pattBgCol);
-	}
-
-	public void setPatternBackgroundColorModified(boolean modified)
-	{
-		setModified(modified,pattBgCol);
-	}
-
-	private boolean getOptionFlag(BitField field)
-	{
-		return field.isSet(field_5_options);
-	}
-
-	private void setOptionFlag(boolean flag, BitField field)
-	{
-		field_5_options = field.setBoolean(field_5_options, flag);
-	}
-
-	/**
-	 * get the stack of the 1st expression as a list
-	 *
-	 * @return list of tokens (casts stack to a list and returns it!)
-	 * this method can return null is we are unable to create Ptgs from
-	 *	 existing excel file
-	 * callers should check for null!
-	 */
-
-	public Ptg[] getParsedExpression1()
-	{
-		return field_17_formula1.getTokens();
-	}
-	public void setParsedExpression1(Ptg[] ptgs) {
-		field_17_formula1 = Formula.create(ptgs);
-	}
-
-	/**
-	 * get the stack of the 2nd expression as a list
-	 *
-	 * @return array of {@link Ptg}s, possibly <code>null</code>
-	 */
-	public Ptg[] getParsedExpression2() {
-		return Formula.getTokens(field_18_formula2);
-	}
-	public void setParsedExpression2(Ptg[] ptgs) {
-		field_18_formula2 = Formula.create(ptgs);
-	}
-
-	public short getSid()
-	{
-		return sid;
-	}
-
-	/**
-	 * @param ptgs must not be <code>null</code>
-	 * @return encoded size of the formula tokens (does not include 2 bytes for ushort length)
-	 */
-	private static int getFormulaSize(Formula formula) {
-		return formula.getEncodedTokenSize();
-	}
-
-	/**
-	 * called by the class that is responsible for writing this sucker.
-	 * Subclasses should implement this so that their data is passed back in a
-	 * byte array.
-	 *
-	 * @param out the stream to write to
-	 */
-	public void serialize(LittleEndianOutput out) {
-
-		int formula1Len=getFormulaSize(field_17_formula1);
-		int formula2Len=getFormulaSize(field_18_formula2);
-
-		out.writeByte(field_1_condition_type);
-		out.writeByte(field_2_comparison_operator);
-		out.writeShort(formula1Len);
-		out.writeShort(formula2Len);
-		out.writeInt(field_5_options);
-		out.writeShort(field_6_not_used);
-
-		if (containsFontFormattingBlock()) {
-			byte[] fontFormattingRawRecord  = _fontFormatting.getRawRecord();
-			out.write(fontFormattingRawRecord);
-		}
-
-		if (containsBorderFormattingBlock()) {
-			_borderFormatting.serialize(out);
-		}
-
-		if (containsPatternFormattingBlock()) {
-			_patternFormatting.serialize(out);
-		}
-
-		field_17_formula1.serializeTokens(out);
-		field_18_formula2.serializeTokens(out);
-	}
-
-	protected int getDataSize() {
-		int i = 12 +
-					(containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+
-					(containsBorderFormattingBlock()?8:0)+
-					(containsPatternFormattingBlock()?4:0)+
-					getFormulaSize(field_17_formula1)+
-					getFormulaSize(field_18_formula2);
-        return i
-					;
-	}
-
-
-	public String toString() {
-		StringBuffer buffer = new StringBuffer();
-		buffer.append("[CFRULE]\n");
-        buffer.append("    .condition_type   =").append(field_1_condition_type).append("\n");
-		buffer.append("    OPTION FLAGS=0x").append(Integer.toHexString(getOptions())).append("\n");
-		if (containsFontFormattingBlock()) {
-			buffer.append(_fontFormatting.toString()).append("\n");
-		}
-		if (containsBorderFormattingBlock()) {
-			buffer.append(_borderFormatting.toString()).append("\n");
-		}
-		if (containsPatternFormattingBlock()) {
-			buffer.append(_patternFormatting.toString()).append("\n");
-		}
-		buffer.append("    Formula 1 =").append(Arrays.toString(field_17_formula1.getTokens())).append("\n");
-		buffer.append("    Formula 2 =").append(Arrays.toString(field_18_formula2.getTokens())).append("\n");
-		buffer.append("[/CFRULE]\n");
-		return buffer.toString();
-	}
-
-	public Object clone() {
-		CFRuleRecord rec = new CFRuleRecord(field_1_condition_type, field_2_comparison_operator);
-		rec.field_5_options = field_5_options;
-		rec.field_6_not_used = field_6_not_used;
-		if (containsFontFormattingBlock()) {
-			rec._fontFormatting = (FontFormatting) _fontFormatting.clone();
-		}
-		if (containsBorderFormattingBlock()) {
-			rec._borderFormatting = (BorderFormatting) _borderFormatting.clone();
-		}
-		if (containsPatternFormattingBlock()) {
-			rec._patternFormatting = (PatternFormatting) _patternFormatting.clone();
-		}
-		rec.field_17_formula1 = field_17_formula1.copy();
-		rec.field_18_formula2 = field_18_formula2.copy();
-
-		return rec;
-	}
-
-	/**
-	 * TODO - parse conditional format formulas properly i.e. produce tRefN and tAreaN instead of tRef and tArea
-	 * this call will produce the wrong results if the formula contains any cell references
-	 * One approach might be to apply the inverse of SharedFormulaRecord.convertSharedFormulas(Stack, int, int)
-	 * Note - two extra parameters (rowIx & colIx) will be required. They probably come from one of the Region objects.
-	 *
-	 * @return <code>null</code> if <tt>formula</tt> was null.
-	 */
-    private static Ptg[] parseFormula(String formula, HSSFSheet sheet) {
-        if(formula == null) {
-            return null;
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("[CFRULE]\n");
+        buffer.append("    .condition_type   =").append(getConditionType()).append("\n");
+        buffer.append("    OPTION FLAGS=0x").append(Integer.toHexString(getOptions())).append("\n");
+        if (containsFontFormattingBlock()) {
+            buffer.append(_fontFormatting.toString()).append("\n");
         }
-        int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
-        return HSSFFormulaParser.parse(formula, sheet.getWorkbook(), FormulaType.CELL, sheetIndex);
+        if (containsBorderFormattingBlock()) {
+            buffer.append(_borderFormatting.toString()).append("\n");
+        }
+        if (containsPatternFormattingBlock()) {
+            buffer.append(_patternFormatting.toString()).append("\n");
+        }
+        buffer.append("    Formula 1 =").append(Arrays.toString(getFormula1().getTokens())).append("\n");
+        buffer.append("    Formula 2 =").append(Arrays.toString(getFormula2().getTokens())).append("\n");
+        buffer.append("[/CFRULE]\n");
+        return buffer.toString();
+    }
+
+    public Object clone() {
+        CFRuleRecord rec = new CFRuleRecord(getConditionType(), getComparisonOperation());
+        super.copyTo(rec);
+        return rec;
     }
 }
diff --git a/src/java/org/apache/poi/hssf/record/FeatRecord.java b/src/java/org/apache/poi/hssf/record/FeatRecord.java
index 572d695..fd583a3 100644
--- a/src/java/org/apache/poi/hssf/record/FeatRecord.java
+++ b/src/java/org/apache/poi/hssf/record/FeatRecord.java
@@ -34,8 +34,11 @@
  *  up with a {@link FeatHdrRecord}.
  */
 public final class FeatRecord extends StandardRecord  {
-	private static POILogger logger = POILogFactory.getLogger(FeatRecord.class);
-	public final static short sid = 0x0868;
+    private static POILogger logger = POILogFactory.getLogger(FeatRecord.class);
+    public final static short sid = 0x0868;
+    // SIDs from newer versions
+    public final static short v11_sid = 0x0872;
+    public final static short v12_sid = 0x0878;
 	
 	private FtrHeader futureHeader;
 	
diff --git a/src/java/org/apache/poi/hssf/record/NameCommentRecord.java b/src/java/org/apache/poi/hssf/record/NameCommentRecord.java
index ed33c2d..6b3c8d0 100644
--- a/src/java/org/apache/poi/hssf/record/NameCommentRecord.java
+++ b/src/java/org/apache/poi/hssf/record/NameCommentRecord.java
@@ -62,17 +62,27 @@
     out.writeShort(field_4_name_length);
     out.writeShort(field_5_comment_length);
 
-    out.writeByte(0);
-    StringUtil.putCompressedUnicode(field_6_name_text, out);
-    out.writeByte(0);
-    StringUtil.putCompressedUnicode(field_7_comment_text, out);
+    boolean isNameMultiByte = StringUtil.hasMultibyte(field_6_name_text);
+    out.writeByte(isNameMultiByte ? 1 : 0);
+    if (isNameMultiByte) {
+        StringUtil.putUnicodeLE(field_6_name_text, out);
+    } else {
+        StringUtil.putCompressedUnicode(field_6_name_text, out);
+    }
+    boolean isCommentMultiByte = StringUtil.hasMultibyte(field_7_comment_text);
+    out.writeByte(isCommentMultiByte ? 1 : 0);
+    if (isCommentMultiByte) {
+        StringUtil.putUnicodeLE(field_7_comment_text, out);
+    } else {
+        StringUtil.putCompressedUnicode(field_7_comment_text, out);
+    }
   }
 
   @Override
   protected int getDataSize() {
     return 18 // 4 shorts + 1 long + 2 spurious 'nul's
-         + field_6_name_text.length()
-         + field_7_comment_text.length();
+         + (StringUtil.hasMultibyte(field_6_name_text) ? field_6_name_text.length()*2 : field_6_name_text.length())
+         + (StringUtil.hasMultibyte(field_7_comment_text) ? field_7_comment_text.length()*2 : field_7_comment_text.length());
   }
 
   /**
@@ -86,10 +96,16 @@
     final int field_4_name_length = in.readShort();
     final int field_5_comment_length = in.readShort();
 
-    in.readByte(); //spurious NUL
-    field_6_name_text = StringUtil.readCompressedUnicode(in, field_4_name_length);
-    in.readByte(); //spurious NUL
-    field_7_comment_text = StringUtil.readCompressedUnicode(in, field_5_comment_length);
+    if (in.readByte() == 0) {
+        field_6_name_text = StringUtil.readCompressedUnicode(in, field_4_name_length);
+    } else {
+        field_6_name_text = StringUtil.readUnicodeLE(in, field_4_name_length);
+    }
+    if (in.readByte() == 0) {
+        field_7_comment_text = StringUtil.readCompressedUnicode(in, field_5_comment_length);
+    } else {
+        field_7_comment_text = StringUtil.readUnicodeLE(in, field_5_comment_length);
+    }    
   }
 
   /**
diff --git a/src/java/org/apache/poi/hssf/record/NameRecord.java b/src/java/org/apache/poi/hssf/record/NameRecord.java
index 904133c..2f7f818 100644
--- a/src/java/org/apache/poi/hssf/record/NameRecord.java
+++ b/src/java/org/apache/poi/hssf/record/NameRecord.java
@@ -411,11 +411,12 @@
 	 * @return extern sheet index
 	 */
 	public int getExternSheetNumber(){
-		if (field_13_name_definition.getEncodedSize() < 1) {
+	    Ptg[] tokens = field_13_name_definition.getTokens();
+		if (tokens.length == 0) {
 			return 0;
 		}
-		Ptg ptg = field_13_name_definition.getTokens()[0];
 
+		Ptg ptg = tokens[0];
 		if (ptg.getClass() == Area3DPtg.class){
 			return ((Area3DPtg) ptg).getExternSheetIndex();
 
diff --git a/src/java/org/apache/poi/hssf/record/RecordFactory.java b/src/java/org/apache/poi/hssf/record/RecordFactory.java
index 3a1f7ac..c1a0f57 100644
--- a/src/java/org/apache/poi/hssf/record/RecordFactory.java
+++ b/src/java/org/apache/poi/hssf/record/RecordFactory.java
@@ -62,425 +62,420 @@
  * Description:  Takes a stream and outputs an array of Record objects.<P>
  *
  * @see org.apache.poi.hssf.eventmodel.EventRecordFactory
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Marc Johnson (mjohnson at apache dot org)
- * @author Glen Stampoultzis (glens at apache.org)
- * @author Csaba Nagy (ncsaba at yahoo dot com)
  */
 public final class RecordFactory {
-	private static final int NUM_RECORDS = 512;
+    private static final int NUM_RECORDS = 512;
 
-	private interface I_RecordCreator {
-		Record create(RecordInputStream in);
+    private interface I_RecordCreator {
+        Record create(RecordInputStream in);
 
-		Class<? extends Record> getRecordClass();
-	}
-	private static final class ReflectionConstructorRecordCreator implements I_RecordCreator {
+        Class<? extends Record> getRecordClass();
+    }
+    private static final class ReflectionConstructorRecordCreator implements I_RecordCreator {
 
-		private final Constructor<? extends Record> _c;
-		public ReflectionConstructorRecordCreator(Constructor<? extends Record> c) {
-			_c = c;
-		}
-		public Record create(RecordInputStream in) {
-			Object[] args = { in, };
-			try {
-				return _c.newInstance(args);
-			} catch (IllegalArgumentException e) {
-				throw new RuntimeException(e);
-			} catch (InstantiationException e) {
-				throw new RuntimeException(e);
-			} catch (IllegalAccessException e) {
-				throw new RuntimeException(e);
-			} catch (InvocationTargetException e) {
-				Throwable t = e.getTargetException();
-				if (t instanceof RecordFormatException) {
-					throw (RecordFormatException)t;
-				} else if (t instanceof EncryptedDocumentException) {
-					throw (EncryptedDocumentException)t;
-				} else {
-				    throw new RecordFormatException("Unable to construct record instance" , t);
-				}
-			}
-		}
-		public Class<? extends Record> getRecordClass() {
-			return _c.getDeclaringClass();
-		}
-	}
-	/**
-	 * A "create" method is used instead of the usual constructor if the created record might
-	 * be of a different class to the declaring class.
-	 */
-	private static final class ReflectionMethodRecordCreator implements I_RecordCreator {
+        private final Constructor<? extends Record> _c;
+        public ReflectionConstructorRecordCreator(Constructor<? extends Record> c) {
+            _c = c;
+        }
+        public Record create(RecordInputStream in) {
+            Object[] args = { in, };
+            try {
+                return _c.newInstance(args);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException(e);
+            } catch (InstantiationException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException(e);
+            } catch (InvocationTargetException e) {
+                Throwable t = e.getTargetException();
+                if (t instanceof RecordFormatException) {
+                    throw (RecordFormatException)t;
+                } else if (t instanceof EncryptedDocumentException) {
+                    throw (EncryptedDocumentException)t;
+                } else {
+                    throw new RecordFormatException("Unable to construct record instance" , t);
+                }
+            }
+        }
+        public Class<? extends Record> getRecordClass() {
+            return _c.getDeclaringClass();
+        }
+    }
+    /**
+     * A "create" method is used instead of the usual constructor if the created record might
+     * be of a different class to the declaring class.
+     */
+    private static final class ReflectionMethodRecordCreator implements I_RecordCreator {
+        private final Method _m;
+        public ReflectionMethodRecordCreator(Method m) {
+            _m = m;
+        }
+        public Record create(RecordInputStream in) {
+            Object[] args = { in, };
+            try {
+                return (Record) _m.invoke(null, args);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException(e);
+            } catch (InvocationTargetException e) {
+                throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
+            }
+        }
+        @SuppressWarnings("unchecked")
+        public Class<? extends Record> getRecordClass() {
+            return (Class<? extends Record>) _m.getDeclaringClass();
+        }
+    }
 
-		private final Method _m;
-		public ReflectionMethodRecordCreator(Method m) {
-			_m = m;
-		}
-		public Record create(RecordInputStream in) {
-			Object[] args = { in, };
-			try {
-				return (Record) _m.invoke(null, args);
-			} catch (IllegalArgumentException e) {
-				throw new RuntimeException(e);
-			} catch (IllegalAccessException e) {
-				throw new RuntimeException(e);
-			} catch (InvocationTargetException e) {
-				throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
-			}
-		}
-		@SuppressWarnings("unchecked")
-		public Class<? extends Record> getRecordClass() {
-			return (Class<? extends Record>) _m.getDeclaringClass();
-		}
-	}
+    private static final Class<?>[] CONSTRUCTOR_ARGS = { RecordInputStream.class, };
 
-
-	private static final Class<?>[] CONSTRUCTOR_ARGS = { RecordInputStream.class, };
-
-	/**
-	 * contains the classes for all the records we want to parse.<br/>
-	 * Note - this most but not *every* subclass of Record.
-	 */
-	@SuppressWarnings("unchecked")
-	private static final Class<? extends Record>[] recordClasses = new Class[] {
-		ArrayRecord.class,
+    /**
+     * contains the classes for all the records we want to parse.<br/>
+     * Note - this most but not *every* subclass of Record.
+     */
+    @SuppressWarnings("unchecked")
+    private static final Class<? extends Record>[] recordClasses = new Class[] {
+        ArrayRecord.class,
         AutoFilterInfoRecord.class,
         BackupRecord.class,
-		BlankRecord.class,
-		BOFRecord.class,
-		BookBoolRecord.class,
-		BoolErrRecord.class,
-		BottomMarginRecord.class,
-		BoundSheetRecord.class,
-		CalcCountRecord.class,
-		CalcModeRecord.class,
-		CFHeaderRecord.class,
-		CFRuleRecord.class,
-		ChartRecord.class,
-		ChartTitleFormatRecord.class,
-		CodepageRecord.class,
-		ColumnInfoRecord.class,
-		ContinueRecord.class,
-		CountryRecord.class,
-		CRNCountRecord.class,
-		CRNRecord.class,
-		DateWindow1904Record.class,
-		DBCellRecord.class,
-                DConRefRecord.class,
-		DefaultColWidthRecord.class,
-		DefaultRowHeightRecord.class,
-		DeltaRecord.class,
-		DimensionsRecord.class,
-		DrawingGroupRecord.class,
-		DrawingRecord.class,
-		DrawingSelectionRecord.class,
-		DSFRecord.class,
-		DVALRecord.class,
-		DVRecord.class,
-		EOFRecord.class,
-		ExtendedFormatRecord.class,
-		ExternalNameRecord.class,
-		ExternSheetRecord.class,
-		ExtSSTRecord.class,
-		FeatRecord.class,
-		FeatHdrRecord.class,
-		FilePassRecord.class,
-		FileSharingRecord.class,
-		FnGroupCountRecord.class,
-		FontRecord.class,
-		FooterRecord.class,
-		FormatRecord.class,
-		FormulaRecord.class,
-		GridsetRecord.class,
-		GutsRecord.class,
-		HCenterRecord.class,
-		HeaderRecord.class,
+        BlankRecord.class,
+        BOFRecord.class,
+        BookBoolRecord.class,
+        BoolErrRecord.class,
+        BottomMarginRecord.class,
+        BoundSheetRecord.class,
+        CalcCountRecord.class,
+        CalcModeRecord.class,
+        CFHeaderRecord.class,
+        CFHeader12Record.class,
+        CFRuleRecord.class,
+        CFRule12Record.class,
+        ChartRecord.class,
+        ChartTitleFormatRecord.class,
+        CodepageRecord.class,
+        ColumnInfoRecord.class,
+        ContinueRecord.class,
+        CountryRecord.class,
+        CRNCountRecord.class,
+        CRNRecord.class,
+        DateWindow1904Record.class,
+        DBCellRecord.class,
+        DConRefRecord.class,
+        DefaultColWidthRecord.class,
+        DefaultRowHeightRecord.class,
+        DeltaRecord.class,
+        DimensionsRecord.class,
+        DrawingGroupRecord.class,
+        DrawingRecord.class,
+        DrawingSelectionRecord.class,
+        DSFRecord.class,
+        DVALRecord.class,
+        DVRecord.class,
+        EOFRecord.class,
+        ExtendedFormatRecord.class,
+        ExternalNameRecord.class,
+        ExternSheetRecord.class,
+        ExtSSTRecord.class,
+        FeatRecord.class,
+        FeatHdrRecord.class,
+        FilePassRecord.class,
+        FileSharingRecord.class,
+        FnGroupCountRecord.class,
+        FontRecord.class,
+        FooterRecord.class,
+        FormatRecord.class,
+        FormulaRecord.class,
+        GridsetRecord.class,
+        GutsRecord.class,
+        HCenterRecord.class,
+        HeaderRecord.class,
         HeaderFooterRecord.class,
-		HideObjRecord.class,
-		HorizontalPageBreakRecord.class,
-		HyperlinkRecord.class,
-		IndexRecord.class,
-		InterfaceEndRecord.class,
-		InterfaceHdrRecord.class,
-		IterationRecord.class,
-		LabelRecord.class,
-		LabelSSTRecord.class,
-		LeftMarginRecord.class,
-		LegendRecord.class,
-		MergeCellsRecord.class,
-		MMSRecord.class,
-		MulBlankRecord.class,
-		MulRKRecord.class,
-		NameRecord.class,
-		NameCommentRecord.class,
-		NoteRecord.class,
-		NumberRecord.class,
-		ObjectProtectRecord.class,
-		ObjRecord.class,
-		PaletteRecord.class,
-		PaneRecord.class,
-		PasswordRecord.class,
-		PasswordRev4Record.class,
-		PrecisionRecord.class,
-		PrintGridlinesRecord.class,
-		PrintHeadersRecord.class,
-		PrintSetupRecord.class,
-		ProtectionRev4Record.class,
-		ProtectRecord.class,
-		RecalcIdRecord.class,
-		RefModeRecord.class,
-		RefreshAllRecord.class,
-		RightMarginRecord.class,
-		RKRecord.class,
-		RowRecord.class,
-		SaveRecalcRecord.class,
-		ScenarioProtectRecord.class,
-		SelectionRecord.class,
-		SeriesRecord.class,
-		SeriesTextRecord.class,
-		SharedFormulaRecord.class,
-		SSTRecord.class,
-		StringRecord.class,
-		StyleRecord.class,
-		SupBookRecord.class,
-		TabIdRecord.class,
-		TableRecord.class,
-		TableStylesRecord.class,
-		TextObjectRecord.class,
-		TopMarginRecord.class,
-		UncalcedRecord.class,
-		UseSelFSRecord.class,
-		UserSViewBegin.class,
-		UserSViewEnd.class,
-		ValueRangeRecord.class,
-		VCenterRecord.class,
-		VerticalPageBreakRecord.class,
-		WindowOneRecord.class,
-		WindowProtectRecord.class,
-		WindowTwoRecord.class,
-		WriteAccessRecord.class,
-		WriteProtectRecord.class,
-		WSBoolRecord.class,
+        HideObjRecord.class,
+        HorizontalPageBreakRecord.class,
+        HyperlinkRecord.class,
+        IndexRecord.class,
+        InterfaceEndRecord.class,
+        InterfaceHdrRecord.class,
+        IterationRecord.class,
+        LabelRecord.class,
+        LabelSSTRecord.class,
+        LeftMarginRecord.class,
+        LegendRecord.class,
+        MergeCellsRecord.class,
+        MMSRecord.class,
+        MulBlankRecord.class,
+        MulRKRecord.class,
+        NameRecord.class,
+        NameCommentRecord.class,
+        NoteRecord.class,
+        NumberRecord.class,
+        ObjectProtectRecord.class,
+        ObjRecord.class,
+        PaletteRecord.class,
+        PaneRecord.class,
+        PasswordRecord.class,
+        PasswordRev4Record.class,
+        PrecisionRecord.class,
+        PrintGridlinesRecord.class,
+        PrintHeadersRecord.class,
+        PrintSetupRecord.class,
+        ProtectionRev4Record.class,
+        ProtectRecord.class,
+        RecalcIdRecord.class,
+        RefModeRecord.class,
+        RefreshAllRecord.class,
+        RightMarginRecord.class,
+        RKRecord.class,
+        RowRecord.class,
+        SaveRecalcRecord.class,
+        ScenarioProtectRecord.class,
+        SelectionRecord.class,
+        SeriesRecord.class,
+        SeriesTextRecord.class,
+        SharedFormulaRecord.class,
+        SSTRecord.class,
+        StringRecord.class,
+        StyleRecord.class,
+        SupBookRecord.class,
+        TabIdRecord.class,
+        TableRecord.class,
+        TableStylesRecord.class,
+        TextObjectRecord.class,
+        TopMarginRecord.class,
+        UncalcedRecord.class,
+        UseSelFSRecord.class,
+        UserSViewBegin.class,
+        UserSViewEnd.class,
+        ValueRangeRecord.class,
+        VCenterRecord.class,
+        VerticalPageBreakRecord.class,
+        WindowOneRecord.class,
+        WindowProtectRecord.class,
+        WindowTwoRecord.class,
+        WriteAccessRecord.class,
+        WriteProtectRecord.class,
+        WSBoolRecord.class,
 
-		// chart records
-		BeginRecord.class,
-		ChartFRTInfoRecord.class,
-		ChartStartBlockRecord.class,
-		ChartEndBlockRecord.class,
-// TODO ChartFormatRecord.class,
-		ChartStartObjectRecord.class,
-		ChartEndObjectRecord.class,
-		CatLabRecord.class,
-      DataFormatRecord.class,
-		EndRecord.class,
-		LinkedDataRecord.class,
-		SeriesToChartGroupRecord.class,
+        // chart records
+        BeginRecord.class,
+        ChartFRTInfoRecord.class,
+        ChartStartBlockRecord.class,
+        ChartEndBlockRecord.class,
+        // TODO ChartFormatRecord.class,
+        ChartStartObjectRecord.class,
+        ChartEndObjectRecord.class,
+        CatLabRecord.class,
+        DataFormatRecord.class,
+        EndRecord.class,
+        LinkedDataRecord.class,
+        SeriesToChartGroupRecord.class,
 
-		// pivot table records
-		DataItemRecord.class,
-		ExtendedPivotTableViewFieldsRecord.class,
-		PageItemRecord.class,
-		StreamIDRecord.class,
-		ViewDefinitionRecord.class,
-		ViewFieldsRecord.class,
-		ViewSourceRecord.class,
-	};
+        // pivot table records
+        DataItemRecord.class,
+        ExtendedPivotTableViewFieldsRecord.class,
+        PageItemRecord.class,
+        StreamIDRecord.class,
+        ViewDefinitionRecord.class,
+        ViewFieldsRecord.class,
+        ViewSourceRecord.class,
+    };
 
-	/**
-	 * cache of the recordsToMap();
-	 */
-	private static final Map<Integer, I_RecordCreator> _recordCreatorsById  = recordsToMap(recordClasses);
+    /**
+     * cache of the recordsToMap();
+     */
+    private static final Map<Integer, I_RecordCreator> _recordCreatorsById  = recordsToMap(recordClasses);
 
-	private static short[] _allKnownRecordSIDs;
+    private static short[] _allKnownRecordSIDs;
 
-	/**
-	 * Debug / diagnosis method<br/>
-	 * Gets the POI implementation class for a given <tt>sid</tt>.  Only a subset of the any BIFF
-	 * records are actually interpreted by POI.  A few others are known but not interpreted
-	 * (see {@link UnknownRecord#getBiffName(int)}).
-	 * @return the POI implementation class for the specified record <tt>sid</tt>.
-	 * <code>null</code> if the specified record is not interpreted by POI.
-	 */
-	public static Class<? extends Record> getRecordClass(int sid) {
-		I_RecordCreator rc = _recordCreatorsById.get(Integer.valueOf(sid));
-		if (rc == null) {
-			return null;
-		}
-		return rc.getRecordClass();
-	}
-	/**
-	 * create a record, if there are MUL records than multiple records
-	 * are returned digested into the non-mul form.
-	 */
-	public static Record [] createRecord(RecordInputStream in) {
+    /**
+     * Debug / diagnosis method<br/>
+     * Gets the POI implementation class for a given <tt>sid</tt>.  Only a subset of the any BIFF
+     * records are actually interpreted by POI.  A few others are known but not interpreted
+     * (see {@link UnknownRecord#getBiffName(int)}).
+     * @return the POI implementation class for the specified record <tt>sid</tt>.
+     * <code>null</code> if the specified record is not interpreted by POI.
+     */
+    public static Class<? extends Record> getRecordClass(int sid) {
+        I_RecordCreator rc = _recordCreatorsById.get(Integer.valueOf(sid));
+        if (rc == null) {
+            return null;
+        }
+        return rc.getRecordClass();
+    }
+    /**
+     * create a record, if there are MUL records than multiple records
+     * are returned digested into the non-mul form.
+     */
+    public static Record [] createRecord(RecordInputStream in) {
+        Record record = createSingleRecord(in);
+        if (record instanceof DBCellRecord) {
+            // Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
+            return new Record[] { null, };
+        }
+        if (record instanceof RKRecord) {
+            return new Record[] { convertToNumberRecord((RKRecord) record), };
+        }
+        if (record instanceof MulRKRecord) {
+            return convertRKRecords((MulRKRecord)record);
+        }
+        return new Record[] { record, };
+    }
 
-		Record record = createSingleRecord(in);
-		if (record instanceof DBCellRecord) {
-			// Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
-			return new Record[] { null, };
-		}
-		if (record instanceof RKRecord) {
-			return new Record[] { convertToNumberRecord((RKRecord) record), };
-		}
-		if (record instanceof MulRKRecord) {
-			return convertRKRecords((MulRKRecord)record);
-		}
-		return new Record[] { record, };
-	}
+    public static Record createSingleRecord(RecordInputStream in) {
+        I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid()));
 
-	public static Record createSingleRecord(RecordInputStream in) {
-		I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid()));
+        if (constructor == null) {
+            return new UnknownRecord(in);
+        }
 
-		if (constructor == null) {
-			return new UnknownRecord(in);
-		}
+        return constructor.create(in);
+    }
 
-		return constructor.create(in);
-	}
+    /**
+     * RK record is a slightly smaller alternative to NumberRecord
+     * POI likes NumberRecord better
+     */
+    public static NumberRecord convertToNumberRecord(RKRecord rk) {
+        NumberRecord num = new NumberRecord();
 
-	/**
-	 * RK record is a slightly smaller alternative to NumberRecord
-	 * POI likes NumberRecord better
-	 */
-	public static NumberRecord convertToNumberRecord(RKRecord rk) {
-		NumberRecord num = new NumberRecord();
+        num.setColumn(rk.getColumn());
+        num.setRow(rk.getRow());
+        num.setXFIndex(rk.getXFIndex());
+        num.setValue(rk.getRKNumber());
+        return num;
+    }
 
-		num.setColumn(rk.getColumn());
-		num.setRow(rk.getRow());
-		num.setXFIndex(rk.getXFIndex());
-		num.setValue(rk.getRKNumber());
-		return num;
-	}
+    /**
+     * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
+     */
+    public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
+        NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
+        for (int k = 0; k < mrk.getNumColumns(); k++) {
+            NumberRecord nr = new NumberRecord();
 
-	/**
-	 * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
-	 */
-	public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
-		NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
-		for (int k = 0; k < mrk.getNumColumns(); k++) {
-			NumberRecord nr = new NumberRecord();
+            nr.setColumn((short) (k + mrk.getFirstColumn()));
+            nr.setRow(mrk.getRow());
+            nr.setXFIndex(mrk.getXFAt(k));
+            nr.setValue(mrk.getRKNumberAt(k));
+            mulRecs[k] = nr;
+        }
+        return mulRecs;
+    }
 
-			nr.setColumn((short) (k + mrk.getFirstColumn()));
-			nr.setRow(mrk.getRow());
-			nr.setXFIndex(mrk.getXFAt(k));
-			nr.setValue(mrk.getRKNumberAt(k));
-			mulRecs[k] = nr;
-		}
-		return mulRecs;
-	}
+    /**
+     * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s
+     */
+    public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) {
+        BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()];
+        for (int k = 0; k < mbk.getNumColumns(); k++) {
+            BlankRecord br = new BlankRecord();
 
-	/**
-	 * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s
-	 */
-	public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) {
-		BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()];
-		for (int k = 0; k < mbk.getNumColumns(); k++) {
-			BlankRecord br = new BlankRecord();
+            br.setColumn((short) (k + mbk.getFirstColumn()));
+            br.setRow(mbk.getRow());
+            br.setXFIndex(mbk.getXFAt(k));
+            mulRecs[k] = br;
+        }
+        return mulRecs;
+    }
 
-			br.setColumn((short) (k + mbk.getFirstColumn()));
-			br.setRow(mbk.getRow());
-			br.setXFIndex(mbk.getXFAt(k));
-			mulRecs[k] = br;
-		}
-		return mulRecs;
-	}
+    /**
+     * @return an array of all the SIDS for all known records
+     */
+    public static short[] getAllKnownRecordSIDs() {
+        if (_allKnownRecordSIDs == null) {
+            short[] results = new short[ _recordCreatorsById.size() ];
+            int i = 0;
 
-	/**
-	 * @return an array of all the SIDS for all known records
-	 */
-	public static short[] getAllKnownRecordSIDs() {
-		if (_allKnownRecordSIDs == null) {
-			short[] results = new short[ _recordCreatorsById.size() ];
-			int i = 0;
+            for (Iterator<Integer> iterator = _recordCreatorsById.keySet().iterator(); iterator.hasNext(); ) {
+                Integer sid = iterator.next();
 
-			for (Iterator<Integer> iterator = _recordCreatorsById.keySet().iterator(); iterator.hasNext(); ) {
-				Integer sid = iterator.next();
+                results[i++] = sid.shortValue();
+            }
+            Arrays.sort(results);
+            _allKnownRecordSIDs = results;
+        }
 
-				results[i++] = sid.shortValue();
-			}
-			Arrays.sort(results);
- 			_allKnownRecordSIDs = results;
-		}
+        return _allKnownRecordSIDs.clone();
+    }
 
-		return _allKnownRecordSIDs.clone();
-	}
+    /**
+     * gets the record constructors and sticks them in the map by SID
+     * @return map of SIDs to short,short,byte[] constructors for Record classes
+     * most of org.apache.poi.hssf.record.*
+     */
+    private static Map<Integer, I_RecordCreator> recordsToMap(Class<? extends Record> [] records) {
+        Map<Integer, I_RecordCreator> result = new HashMap<Integer, I_RecordCreator>();
+        Set<Class<?>> uniqueRecClasses = new HashSet<Class<?>>(records.length * 3 / 2);
 
-	/**
-	 * gets the record constructors and sticks them in the map by SID
-	 * @return map of SIDs to short,short,byte[] constructors for Record classes
-	 * most of org.apache.poi.hssf.record.*
-	 */
-	private static Map<Integer, I_RecordCreator> recordsToMap(Class<? extends Record> [] records) {
-		Map<Integer, I_RecordCreator> result = new HashMap<Integer, I_RecordCreator>();
-		Set<Class<?>> uniqueRecClasses = new HashSet<Class<?>>(records.length * 3 / 2);
+        for (int i = 0; i < records.length; i++) {
 
-		for (int i = 0; i < records.length; i++) {
+            Class<? extends Record> recClass = records[ i ];
+            if(!Record.class.isAssignableFrom(recClass)) {
+                throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")");
+            }
+            if(Modifier.isAbstract(recClass.getModifiers())) {
+                throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract");
+            }
+            if(!uniqueRecClasses.add(recClass)) {
+                throw new RuntimeException("duplicate record class (" + recClass.getName() + ")");
+            }
 
-			Class<? extends Record> recClass = records[ i ];
-			if(!Record.class.isAssignableFrom(recClass)) {
-				throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")");
-			}
-			if(Modifier.isAbstract(recClass.getModifiers())) {
-				throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract");
-			}
-			if(!uniqueRecClasses.add(recClass)) {
-				throw new RuntimeException("duplicate record class (" + recClass.getName() + ")");
-			}
+            int sid;
+            try {
+                sid = recClass.getField("sid").getShort(null);
+            } catch (Exception illegalArgumentException) {
+                throw new RecordFormatException(
+                        "Unable to determine record types");
+            }
+            Integer key = Integer.valueOf(sid);
+            if (result.containsKey(key)) {
+                Class<?> prevClass = result.get(key).getRecordClass();
+                throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase()
+                        + " for classes (" + recClass.getName() + ") and (" + prevClass.getName() + ")");
+            }
+            result.put(key, getRecordCreator(recClass));
+        }
+        // result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06)));
+        return result;
+    }
 
-			int sid;
-			try {
-				sid = recClass.getField("sid").getShort(null);
-			} catch (Exception illegalArgumentException) {
-				throw new RecordFormatException(
-					"Unable to determine record types");
-			}
-			Integer key = Integer.valueOf(sid);
-			if (result.containsKey(key)) {
-				Class<?> prevClass = result.get(key).getRecordClass();
-				throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase()
-						+ " for classes (" + recClass.getName() + ") and (" + prevClass.getName() + ")");
-			}
-			result.put(key, getRecordCreator(recClass));
-		}
-//		result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06)));
-		return result;
-	}
+    private static I_RecordCreator getRecordCreator(Class<? extends Record> recClass) {
+        try {
+            Constructor<? extends Record> constructor;
+            constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
+            return new ReflectionConstructorRecordCreator(constructor);
+        } catch (NoSuchMethodException e) {
+            // fall through and look for other construction methods
+        }
+        try {
+            Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS);
+            return new ReflectionMethodRecordCreator(m);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ").");
+        }
+    }
+    /**
+     * Create an array of records from an input stream
+     *
+     * @param in the InputStream from which the records will be obtained
+     *
+     * @return an array of Records created from the InputStream
+     *
+     * @exception RecordFormatException on error processing the InputStream
+     */
+    public static List<Record> createRecords(InputStream in) throws RecordFormatException {
 
-	private static I_RecordCreator getRecordCreator(Class<? extends Record> recClass) {
-		try {
-			Constructor<? extends Record> constructor;
-			constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
-			return new ReflectionConstructorRecordCreator(constructor);
-		} catch (NoSuchMethodException e) {
-			// fall through and look for other construction methods
-		}
-		try {
-			Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS);
-			return new ReflectionMethodRecordCreator(m);
-		} catch (NoSuchMethodException e) {
-			throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ").");
-		}
-	}
-	/**
-	 * Create an array of records from an input stream
-	 *
-	 * @param in the InputStream from which the records will be obtained
-	 *
-	 * @return an array of Records created from the InputStream
-	 *
-	 * @exception RecordFormatException on error processing the InputStream
-	 */
-	public static List<Record> createRecords(InputStream in) throws RecordFormatException {
+        List<Record> records = new ArrayList<Record>(NUM_RECORDS);
 
-		List<Record> records = new ArrayList<Record>(NUM_RECORDS);
+        RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true);
 
-		RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true);
+        Record record;
+        while ((record = recStream.nextRecord())!=null) {
+            records.add(record);
+        }
 
-		Record record;
-		while ((record = recStream.nextRecord())!=null) {
-			records.add(record);
-		}
-
-		return records;
-	}
+        return records;
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
index 9f0b16e..9de7d68 100644
--- a/src/java/org/apache/poi/hssf/record/RecordInputStream.java
+++ b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
@@ -52,8 +52,17 @@
 	public static final class LeftoverDataException extends RuntimeException {
 		public LeftoverDataException(int sid, int remainingByteCount) {
 			super("Initialisation of record 0x" + Integer.toHexString(sid).toUpperCase()
-					+ " left " + remainingByteCount + " bytes remaining still to be read.");
+					+ "(" + getRecordName(sid) + ") left " + remainingByteCount 
+					+ " bytes remaining still to be read.");
 		}
+
+        private static String getRecordName(int sid) {
+            Class<? extends Record> recordClass = RecordFactory.getRecordClass(sid);
+            if(recordClass == null) {
+                return null;
+            }
+            return recordClass.getSimpleName();
+        }
 	}
 
 	/** Header {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java
index 75d3f99..ffbf9c7 100644
--- a/src/java/org/apache/poi/hssf/record/RowRecord.java
+++ b/src/java/org/apache/poi/hssf/record/RowRecord.java
@@ -64,6 +64,9 @@
     // bit 15 is unused
 
     public RowRecord(int rowNumber) {
+    	if(rowNumber < 0) {
+    		throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")");
+    	}
         field_1_row_number = rowNumber;
         field_4_height = (short)0xFF;
         field_5_optimize = ( short ) 0;
@@ -76,6 +79,9 @@
 
     public RowRecord(RecordInputStream in) {
         field_1_row_number   = in.readUShort();
+    	if(field_1_row_number < 0) {
+    		throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream");
+    	}
         field_2_first_col    = in.readShort();
         field_3_last_col     = in.readShort();
         field_4_height       = in.readShort();
diff --git a/src/java/org/apache/poi/hssf/record/UnknownRecord.java b/src/java/org/apache/poi/hssf/record/UnknownRecord.java
index 6b46247..f87953a 100644
--- a/src/java/org/apache/poi/hssf/record/UnknownRecord.java
+++ b/src/java/org/apache/poi/hssf/record/UnknownRecord.java
@@ -179,8 +179,10 @@
             case SHEETPROTECTION_0867: return "SHEETPROTECTION";
             case 0x086B: return "DATALABEXTCONTENTS";
             case 0x086C: return "CELLWATCH";
+            case FeatRecord.v11_sid: return "SHARED FEATURE v11";
             case 0x0874: return "DROPDOWNOBJIDS";
             case 0x0876: return "DCONN";
+            case FeatRecord.v12_sid: return "SHARED FEATURE v12";
             case 0x087B: return "CFEX";
             case 0x087C: return "XFCRC";
             case 0x087D: return "XFEXT";
@@ -194,15 +196,21 @@
             case 0x089A: return "MTRSETTINGS";
             case 0x089B: return "COMPRESSPICTURES";
             case HEADER_FOOTER_089C: return "HEADERFOOTER";
+            case 0x089D: return "CRTLAYOUT12";
+            case 0x089E: return "CRTMLFRT";
+            case 0x089F: return "CRTMLFRTCONTINUE";
             case 0x08A1: return "SHAPEPROPSSTREAM";
             case 0x08A3: return "FORCEFULLCALCULATION";
             case 0x08A4: return "SHAPEPROPSSTREAM";
             case 0x08A5: return "TEXTPROPSSTREAM";
             case 0x08A6: return "RICHTEXTSTREAM";
+            case 0x08A7: return "CRTLAYOUT12A";
 
             case 0x08C8: return "PLV{Mac Excel}";
-
-
+            
+            case 0x1001: return "UNITS";
+            case 0x1006: return "CHARTDATAFORMAT";
+            case 0x1007: return "CHARTLINEFORMAT";
         }
         if (isObservedButUnknown(sid)) {
             return "UNKNOWN-" + Integer.toHexString(sid).toUpperCase();
@@ -215,6 +223,7 @@
      * @return <code>true</code> if the unknown record id has been observed in POI unit tests
      */
     private static boolean isObservedButUnknown(int sid) {
+        // TODO Look up more of these in the latest [MS-XLS] doc and move to getBiffName
         switch (sid) {
             case 0x0033:
                 // contains 2 bytes of data: 0x0001 or 0x0003
@@ -227,13 +236,7 @@
                 // Written by Excel 2007
                 // rawData is multiple of 12 bytes long
                 // appears after last cell value record and before WINDOW2 or drawing records
-            case 0x089D:
-            case 0x089E:
-            case 0x08A7:
 
-            case 0x1001:
-            case 0x1006:
-            case 0x1007:
             case 0x1009:
             case 0x100A:
             case 0x100B:
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
index d9d6412..c43e4f5 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
@@ -21,7 +21,11 @@
 import java.util.List;
 
 import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.CFHeader12Record;
+import org.apache.poi.hssf.record.CFHeaderBase;
 import org.apache.poi.hssf.record.CFHeaderRecord;
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.ss.formula.FormulaShifter;
@@ -38,212 +42,240 @@
  * <p>Note that Excel versions before 2007 can only cope with a maximum of 3
  *  Conditional Formatting rules per sheet. Excel 2007 or newer can cope with
  *  unlimited numbers, as can Apache OpenOffice. This is an Excel limitation,
- *  not a file format one.</p> 
+ *  not a file format one.</p>
  */
 public final class CFRecordsAggregate extends RecordAggregate {
-	/** Excel 97-2003 allows up to 3 conditional formating rules */
-	private static final int MAX_97_2003_CONDTIONAL_FORMAT_RULES = 3;
-	private static final POILogger logger = POILogFactory.getLogger(CFRecordsAggregate.class);
+    /** Excel 97-2003 allows up to 3 conditional formating rules */
+    private static final int MAX_97_2003_CONDTIONAL_FORMAT_RULES = 3;
+    private static final POILogger logger = POILogFactory.getLogger(CFRecordsAggregate.class);
 
-	private final CFHeaderRecord header;
+    private final CFHeaderBase header;
 
-	/** List of CFRuleRecord objects */
-	private final List<CFRuleRecord> rules;
+    /** List of CFRuleRecord objects */
+    private final List<CFRuleBase> rules;
 
-	private CFRecordsAggregate(CFHeaderRecord pHeader, CFRuleRecord[] pRules) {
-		if(pHeader == null) {
-			throw new IllegalArgumentException("header must not be null");
-		}
-		if(pRules == null) {
-			throw new IllegalArgumentException("rules must not be null");
-		}
-		if(pRules.length > MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
-		    logger.log(POILogger.WARN, "Excel versions before 2007 require that "
-			        + "No more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
-			        + " rules may be specified, " + pRules.length + " were found,"
-			        + " this file will cause problems with old Excel versions");
-		}
-		if (pRules.length != pHeader.getNumberOfConditionalFormats()) {
-			throw new RuntimeException("Mismatch number of rules");
-		}
-		header = pHeader;
-		rules = new ArrayList<CFRuleRecord>(3);
-		for (int i = 0; i < pRules.length; i++) {
-			rules.add(pRules[i]);
-		}
-	}
+    private CFRecordsAggregate(CFHeaderBase pHeader, CFRuleBase[] pRules) {
+        if(pHeader == null) {
+            throw new IllegalArgumentException("header must not be null");
+        }
+        if(pRules == null) {
+            throw new IllegalArgumentException("rules must not be null");
+        }
+        if(pRules.length > MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
+            logger.log(POILogger.WARN, "Excel versions before 2007 require that "
+                    + "No more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
+                    + " rules may be specified, " + pRules.length + " were found,"
+                    + " this file will cause problems with old Excel versions");
+        }
+        if (pRules.length != pHeader.getNumberOfConditionalFormats()) {
+            throw new RuntimeException("Mismatch number of rules");
+        }
+        header = pHeader;
+        rules = new ArrayList<CFRuleBase>(pRules.length);
+        for (int i = 0; i < pRules.length; i++) {
+            checkRuleType(pRules[i]);
+            rules.add(pRules[i]);
+        }
+    }
 
-	public CFRecordsAggregate(CellRangeAddress[] regions, CFRuleRecord[] rules) {
-		this(new CFHeaderRecord(regions, rules.length), rules);
-	}
+    public CFRecordsAggregate(CellRangeAddress[] regions, CFRuleBase[] rules) {
+        this(createHeader(regions, rules), rules);
+    }
+    private static CFHeaderBase createHeader(CellRangeAddress[] regions, CFRuleBase[] rules) {
+        if (rules.length == 0 || rules[0] instanceof CFRuleRecord) {
+            return new CFHeaderRecord(regions, rules.length);
+        }
+        return new CFHeader12Record(regions, rules.length);
+    }
 
-	/**
-	 * Create CFRecordsAggregate from a list of CF Records
-	 * @param rs - the stream to read from
-	 * @return CFRecordsAggregate object
-	 */
-	public static CFRecordsAggregate createCFAggregate(RecordStream rs) {
-		Record rec = rs.getNext();
-		if (rec.getSid() != CFHeaderRecord.sid) {
-			throw new IllegalStateException("next record sid was " + rec.getSid() 
-					+ " instead of " + CFHeaderRecord.sid + " as expected");
-		}
+    /**
+     * Create CFRecordsAggregate from a list of CF Records
+     * @param rs - the stream to read from
+     * @return CFRecordsAggregate object
+     */
+    public static CFRecordsAggregate createCFAggregate(RecordStream rs) {
+        Record rec = rs.getNext();
+        if (rec.getSid() != CFHeaderRecord.sid &&
+            rec.getSid() != CFHeader12Record.sid) {
+            throw new IllegalStateException("next record sid was " + rec.getSid() 
+                    + " instead of " + CFHeaderRecord.sid + " or " +
+                    CFHeader12Record.sid + " as expected");
+        }
 
-		CFHeaderRecord header = (CFHeaderRecord)rec;
-		int nRules = header.getNumberOfConditionalFormats();
+        CFHeaderBase header = (CFHeaderBase)rec;
+        int nRules = header.getNumberOfConditionalFormats();
 
-		CFRuleRecord[] rules = new CFRuleRecord[nRules];
-		for (int i = 0; i < rules.length; i++) {
-			rules[i] = (CFRuleRecord) rs.getNext();
-		}
-		
-		return new CFRecordsAggregate(header, rules);
-	}
+        CFRuleBase[] rules = new CFRuleBase[nRules];
+        for (int i = 0; i < rules.length; i++) {
+            rules[i] = (CFRuleBase) rs.getNext();
+        }
 
-	/**
-	 * Create a deep clone of the record
-	 */
-	public CFRecordsAggregate cloneCFAggregate()
-	{
-	  
-		CFRuleRecord[] newRecs = new CFRuleRecord[rules.size()];
-		for (int i = 0; i < newRecs.length; i++) {
-			newRecs[i] = (CFRuleRecord) getRule(i).clone();
-		}
-		return new CFRecordsAggregate((CFHeaderRecord) header.clone(), newRecs);
-	}
+        return new CFRecordsAggregate(header, rules);
+    }
 
-	/**
-	 * @return the header. Never <code>null</code>.
-	 */
-	public CFHeaderRecord getHeader()
-	{
-		return header;
-	}
-	
-	private void checkRuleIndex(int idx) {
-		if(idx < 0 || idx >= rules.size()) {
-			throw new IllegalArgumentException("Bad rule record index (" + idx 
-					+ ") nRules=" + rules.size());
-		}
-	}
-	public CFRuleRecord getRule(int idx) {
-		checkRuleIndex(idx);
-		return rules.get(idx);
-	}
-	public void setRule(int idx, CFRuleRecord r) {
-		if (r == null) {
-			throw new IllegalArgumentException("r must not be null");
-		}
-		checkRuleIndex(idx);
-		rules.set(idx, r);
-	}
-	public void addRule(CFRuleRecord r) {
-		if (r == null) {
-			throw new IllegalArgumentException("r must not be null");
-		}
-		if(rules.size() >= MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
+    /**
+     * Create a deep clone of the record
+     */
+    public CFRecordsAggregate cloneCFAggregate() {
+        CFRuleBase[] newRecs = new CFRuleBase[rules.size()];
+        for (int i = 0; i < newRecs.length; i++) {
+            newRecs[i] = (CFRuleRecord) getRule(i).clone();
+        }
+        return new CFRecordsAggregate((CFHeaderBase)header.clone(), newRecs);
+    }
+
+    /**
+     * @return the header. Never <code>null</code>.
+     */
+    public CFHeaderBase getHeader() {
+        return header;
+    }
+
+    private void checkRuleIndex(int idx) {
+        if(idx < 0 || idx >= rules.size()) {
+            throw new IllegalArgumentException("Bad rule record index (" + idx 
+                    + ") nRules=" + rules.size());
+        }
+    }
+    private void checkRuleType(CFRuleBase r) {
+        if (header instanceof CFHeaderRecord &&
+                 r instanceof CFRuleRecord) {
+            return;
+        }
+        if (header instanceof CFHeader12Record &&
+                 r instanceof CFRule12Record) {
+           return;
+        }
+        throw new IllegalArgumentException("Header and Rule must both be CF or both be CF12, can't mix");
+    }
+
+    public CFRuleBase getRule(int idx) {
+        checkRuleIndex(idx);
+        return rules.get(idx);
+    }
+    public void setRule(int idx, CFRuleBase r) {
+        if (r == null) {
+            throw new IllegalArgumentException("r must not be null");
+        }
+        checkRuleIndex(idx);
+        checkRuleType(r);
+        rules.set(idx, r);
+    }
+    public void addRule(CFRuleBase r) {
+        if (r == null) {
+            throw new IllegalArgumentException("r must not be null");
+        }
+        if(rules.size() >= MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
             logger.log(POILogger.WARN, "Excel versions before 2007 cannot cope with" 
-		            + " any more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
+                    + " any more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
                     + " - this file will cause problems with old Excel versions");
-		}
-		rules.add(r);
-		header.setNumberOfConditionalFormats(rules.size());
-	}
-	public int getNumberOfRules() {
-		return rules.size();
-	}
+        }
+        checkRuleType(r);
+        rules.add(r);
+        header.setNumberOfConditionalFormats(rules.size());
+    }
+    public int getNumberOfRules() {
+        return rules.size();
+    }
 
-	/**
-	 * String representation of CFRecordsAggregate
-	 */
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
+    /**
+     * String representation of CFRecordsAggregate
+     */
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        String type = "CF";
+        if (header instanceof CFHeader12Record) {
+            type = "CF12";
+        }
 
-		buffer.append("[CF]\n");
-		if( header != null )
-		{
-			buffer.append(header.toString());
-		}
-		for(int i=0; i<rules.size(); i++)
-		{
-			CFRuleRecord cfRule = rules.get(i);
-			buffer.append(cfRule.toString());
-		}
-		buffer.append("[/CF]\n");
-		return buffer.toString();
-	}
+        buffer.append("[").append(type).append("]\n");
+        if( header != null ) {
+            buffer.append(header.toString());
+        }
+        for(int i=0; i<rules.size(); i++) {
+            CFRuleBase cfRule = rules.get(i);
+            buffer.append(cfRule.toString());
+        }
+        buffer.append("[/").append(type).append("]\n");
+        return buffer.toString();
+    }
 
-	public void visitContainedRecords(RecordVisitor rv) {
-		rv.visitRecord(header);
-		for(int i=0; i<rules.size(); i++) {
-			CFRuleRecord rule = rules.get(i);
-			rv.visitRecord(rule);
-		}
-	}
+    public void visitContainedRecords(RecordVisitor rv) {
+        rv.visitRecord(header);
+        for(int i=0; i<rules.size(); i++) {
+            CFRuleBase rule = rules.get(i);
+            rv.visitRecord(rule);
+        }
+    }
 
-	/**
-	 * @return <code>false</code> if this whole {@link CFHeaderRecord} / {@link CFRuleRecord}s should be deleted
-	 */
-	public boolean updateFormulasAfterCellShift(FormulaShifter shifter, int currentExternSheetIx) {
-		CellRangeAddress[] cellRanges = header.getCellRanges();
-		boolean changed = false;
-		List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
-		for (int i = 0; i < cellRanges.length; i++) {
-			CellRangeAddress craOld = cellRanges[i];
-			CellRangeAddress craNew = shiftRange(shifter, craOld, currentExternSheetIx);
-			if (craNew == null) {
-				changed = true;
-				continue;
-			}
-			temp.add(craNew);
-			if (craNew != craOld) {
-				changed = true;
-			}
-		}
+    /**
+     * @return <code>false</code> if this whole {@link CFHeaderRecord} / {@link CFRuleRecord}s should be deleted
+     */
+    public boolean updateFormulasAfterCellShift(FormulaShifter shifter, int currentExternSheetIx) {
+        CellRangeAddress[] cellRanges = header.getCellRanges();
+        boolean changed = false;
+        List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
+        for (int i = 0; i < cellRanges.length; i++) {
+            CellRangeAddress craOld = cellRanges[i];
+            CellRangeAddress craNew = shiftRange(shifter, craOld, currentExternSheetIx);
+            if (craNew == null) {
+                changed = true;
+                continue;
+            }
+            temp.add(craNew);
+            if (craNew != craOld) {
+                changed = true;
+            }
+        }
 
-		if (changed) {
-			int nRanges = temp.size();
-			if (nRanges == 0) {
-				return false;
-			}
-			CellRangeAddress[] newRanges = new CellRangeAddress[nRanges];
-			temp.toArray(newRanges);
-			header.setCellRanges(newRanges);
-		}
-		
-		for(int i=0; i<rules.size(); i++) {
-			CFRuleRecord rule = rules.get(i);
-			Ptg[] ptgs;
-			ptgs = rule.getParsedExpression1();
-			if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
-				rule.setParsedExpression1(ptgs);
-			}
-			ptgs = rule.getParsedExpression2();
-			if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
-				rule.setParsedExpression2(ptgs);
-			}
-		}
-		return true;
-	}
+        if (changed) {
+            int nRanges = temp.size();
+            if (nRanges == 0) {
+                return false;
+            }
+            CellRangeAddress[] newRanges = new CellRangeAddress[nRanges];
+            temp.toArray(newRanges);
+            header.setCellRanges(newRanges);
+        }
 
-	private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) {
-		// FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here
-		AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false);
-		Ptg[] ptgs = { aptg, };
-		
-		if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) {
-			return cra;
-		}
-		Ptg ptg0 = ptgs[0];
-		if (ptg0 instanceof AreaPtg) {
-			AreaPtg bptg = (AreaPtg) ptg0;
-			return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn());
-		}
-		if (ptg0 instanceof AreaErrPtg) {
-			return null;
-		}
-		throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")");
-	}
+        for(int i=0; i<rules.size(); i++) {
+            CFRuleBase rule = rules.get(i);
+            Ptg[] ptgs;
+            ptgs = rule.getParsedExpression1();
+            if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
+                rule.setParsedExpression1(ptgs);
+            }
+            ptgs = rule.getParsedExpression2();
+            if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
+                rule.setParsedExpression2(ptgs);
+            }
+            if (rule instanceof CFRule12Record) {
+                CFRule12Record rule12 = (CFRule12Record)rule;
+                ptgs = rule12.getParsedExpressionScale();
+                if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
+                    rule12.setParsedExpressionScale(ptgs);
+                }
+            }
+        }
+        return true;
+    }
+
+    private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) {
+        // FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here
+        AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false);
+        Ptg[] ptgs = { aptg, };
+
+        if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) {
+            return cra;
+        }
+        Ptg ptg0 = ptgs[0];
+        if (ptg0 instanceof AreaPtg) {
+            AreaPtg bptg = (AreaPtg) ptg0;
+            return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn());
+        }
+        if (ptg0 instanceof AreaErrPtg) {
+            return null;
+        }
+        throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")");
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java b/src/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java
index 33a2f7b..e4721ca 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.CFHeader12Record;
 import org.apache.poi.hssf.record.CFHeaderRecord;
 import org.apache.poi.ss.formula.FormulaShifter;
 
@@ -28,11 +29,8 @@
  * Holds all the conditional formatting for a workbook sheet.<p/>
  * 
  * See OOO exelfileformat.pdf sec 4.12 'Conditional Formatting Table'
- * 
- * @author Josh Micich
  */
 public final class ConditionalFormattingTable extends RecordAggregate {
-
 	private final List<CFRecordsAggregate> _cfHeaders;
 
 	/**
@@ -45,7 +43,8 @@
 	public ConditionalFormattingTable(RecordStream rs) {
 
 		List<CFRecordsAggregate> temp = new ArrayList<CFRecordsAggregate>();
-		while (rs.peekNextClass() == CFHeaderRecord.class) {
+		while (rs.peekNextClass() == CFHeaderRecord.class ||
+		       rs.peekNextClass() == CFHeader12Record.class) {
 			temp.add(CFRecordsAggregate.createCFAggregate(rs));
 		}
 		_cfHeaders = temp;
@@ -62,6 +61,7 @@
 	 * @return index of the newly added CF header aggregate
 	 */
 	public int add(CFRecordsAggregate cfAggregate) {
+	    cfAggregate.getHeader().setID(_cfHeaders.size());
 		_cfHeaders.add(cfAggregate);
 		return _cfHeaders.size() - 1;
 	}
diff --git a/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java b/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java
index e9eca99..ef003d5 100644
--- a/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java
+++ b/src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java
@@ -25,11 +25,8 @@
 
 /**
  * Border Formatting Block of the Conditional Formatting Rule Record.
- *
- * @author Dmitriy Kumshayev
  */
 public final class BorderFormatting {
-
     /** No border */
     public final static short    BORDER_NONE                = 0x0;
     /** Thin border */
@@ -89,6 +86,9 @@
         field_14_border_styles2    = in.readInt();
     }
 
+    public int getDataLength() {
+        return 8;
+    }
 
     /**
      * set the type of border to use for the left border of the cell
diff --git a/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java b/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
index d1532a9..cde666a 100644
--- a/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
+++ b/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
@@ -23,97 +23,93 @@
 import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
- * 
- * @author Dmitriy Kumshayev
+ * TODO Should this move to org.apache.poi.ss.util ?
  */
-public final class CellRangeUtil
-{
-	
-	private CellRangeUtil() {
-		// no instance of this class
-	}
-	
-	public static final int NO_INTERSECTION = 1;
-	public static final int OVERLAP = 2;
-	/** first range is within the second range */
-	public static final int INSIDE = 3;
-	/** first range encloses or is equal to the second */
-	public static final int ENCLOSES = 4;
-	
-	/**
-	 * Intersect this range with the specified range.
-	 * 
-	 * @param crB - the specified range
-	 * @return code which reflects how the specified range is related to this range.<br/>
-	 * Possible return codes are:	
-	 * 		NO_INTERSECTION - the specified range is outside of this range;<br/> 
-	 * 		OVERLAP - both ranges partially overlap;<br/>
-	 * 		INSIDE - the specified range is inside of this one<br/>
-	 * 		ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
-	 */
-	public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
-	{
-		
-		int firstRow = crB.getFirstRow();
-		int lastRow  = crB.getLastRow();
-		int firstCol = crB.getFirstColumn();
-		int lastCol  = crB.getLastColumn();
-		
-		if
-		( 
+public final class CellRangeUtil {
+    private CellRangeUtil() {
+        // no instance of this class
+    }
+
+    public static final int NO_INTERSECTION = 1;
+    public static final int OVERLAP = 2;
+    /** first range is within the second range */
+    public static final int INSIDE = 3;
+    /** first range encloses or is equal to the second */
+    public static final int ENCLOSES = 4;
+
+    /**
+     * Intersect this range with the specified range.
+     * 
+     * @param crB - the specified range
+     * @return code which reflects how the specified range is related to this range.<br/>
+     * Possible return codes are:	
+     * 		NO_INTERSECTION - the specified range is outside of this range;<br/> 
+     * 		OVERLAP - both ranges partially overlap;<br/>
+     * 		INSIDE - the specified range is inside of this one<br/>
+     * 		ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
+     */
+    public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
+    {
+
+        int firstRow = crB.getFirstRow();
+        int lastRow  = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol  = crB.getLastColumn();
+
+        if
+        ( 
 				gt(crA.getFirstRow(),lastRow) || 
 				lt(crA.getLastRow(),firstRow) ||
 				gt(crA.getFirstColumn(),lastCol) || 
 				lt(crA.getLastColumn(),firstCol) 
-		)
-		{
-			return NO_INTERSECTION;
-		}
-		else if( contains(crA, crB) )
-		{
-			return INSIDE;
-		}
-		else if( contains(crB, crA))
-		{
-			return ENCLOSES;
-		}
-		else
-		{
-			return OVERLAP;
-		}
-			
-	}
-	
-	/**
-	 * Do all possible cell merges between cells of the list so that:<br>
-	 * 	<li>if a cell range is completely inside of another cell range, it gets removed from the list 
-	 * 	<li>if two cells have a shared border, merge them into one bigger cell range
-	 * @param cellRanges
-	 * @return updated List of cell ranges
-	 */
-	public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
-		if(cellRanges.length < 1) {
-			return cellRanges;
-		}
+        )
+        {
+            return NO_INTERSECTION;
+        }
+        else if( contains(crA, crB) )
+        {
+            return INSIDE;
+        }
+        else if( contains(crB, crA))
+        {
+            return ENCLOSES;
+        }
+        else
+        {
+            return OVERLAP;
+        }
+    }
+
+    /**
+     * Do all possible cell merges between cells of the list so that:<br>
+     * 	<li>if a cell range is completely inside of another cell range, it gets removed from the list 
+     * 	<li>if two cells have a shared border, merge them into one bigger cell range
+     * @param cellRanges
+     * @return updated List of cell ranges
+     */
+    public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
+        if(cellRanges.length < 1) {
+            return cellRanges;
+        }
 
         List<CellRangeAddress> lst = new ArrayList<CellRangeAddress>();
         for(CellRangeAddress cr : cellRanges) {
             lst.add(cr);
         }
         List<CellRangeAddress> temp = mergeCellRanges(lst);
-		return toArray(temp);
-	}
+        return toArray(temp);
+    }
 
-	private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
-	{
-	    // loop until either only one item is left or we did not merge anything any more
+    private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
+    {
+        // loop until either only one item is left or we did not merge anything any more
         while (cellRangeList.size() > 1) {
             boolean somethingGotMerged = false;
 
             // look at all cell-ranges
             for (int i = 0; i < cellRangeList.size(); i++) {
                 CellRangeAddress range1 = cellRangeList.get(i);
-                
+
                 // compare each cell range to all other cell-ranges
                 for (int j = i + 1; j < cellRangeList.size(); j++) {
                     CellRangeAddress range2 = cellRangeList.get(j);
@@ -139,16 +135,16 @@
             }
         }
 
-		return cellRangeList;
-	}
-	
-	/**
-	 * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
-	 */
-	private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
-		int x = intersect(range1, range2);
-		switch(x)
-		{
+        return cellRangeList;
+    }
+
+    /**
+     * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
+     */
+    private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
+        int x = intersect(range1, range2);
+        switch(x)
+        {
 			case CellRangeUtil.NO_INTERSECTION: 
 			    // nothing in common: at most they could be adjacent to each other and thus form a single bigger area  
 				if(hasExactSharedBorder(range1, range2)) {
@@ -171,108 +167,103 @@
 		throw new RuntimeException("unexpected intersection result (" + x + ")");
 	}
 
-	
-	private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
-		CellRangeAddress[] result = new CellRangeAddress[temp.size()];
-		temp.toArray(result);
-		return result;
-	}
+    private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
+        CellRangeAddress[] result = new CellRangeAddress[temp.size()];
+        temp.toArray(result);
+        return result;
+    }
 
+    /**
+     *  Check if the specified range is located inside of this cell range.
+     *  
+     * @param crB
+     * @return true if this cell range contains the argument range inside if it's area
+     */
+    public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
+    {
+        int firstRow = crB.getFirstRow();
+        int lastRow = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol = crB.getLastColumn();
+        return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
+                && le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
+    }
 
+    /**
+     * Check if the two cell ranges have a shared border.
+     * 
+     * @return <code>true</code> if the ranges have a complete shared border (i.e.
+     * the two ranges together make a simple rectangular region.
+     */
+    public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
+        int oFirstRow = crB.getFirstRow();
+        int oLastRow  = crB.getLastRow();
+        int oFirstCol = crB.getFirstColumn();
+        int oLastCol  = crB.getLastColumn();
 
-	/**
-	 *  Check if the specified range is located inside of this cell range.
-	 *  
-	 * @param crB
-	 * @return true if this cell range contains the argument range inside if it's area
-	 */
-   public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
-   {
-		int firstRow = crB.getFirstRow();
-		int lastRow = crB.getLastRow();
-		int firstCol = crB.getFirstColumn();
-		int lastCol = crB.getLastColumn();
-		return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
-				&& le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
-	}
-   	
-   /**
-	* Check if the two cell ranges have a shared border.
-	* 
-	* @return <code>true</code> if the ranges have a complete shared border (i.e.
-	* the two ranges together make a simple rectangular region.
-	*/
-   	public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
-		int oFirstRow = crB.getFirstRow();
-		int oLastRow  = crB.getLastRow();
-		int oFirstCol = crB.getFirstColumn();
-		int oLastCol  = crB.getLastColumn();
-		
-		if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
-			oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
-			// ranges have a horizontal border in common
-			// make sure columns are identical:
-			return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
-		}
+        if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
+                oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
+            // ranges have a horizontal border in common
+            // make sure columns are identical:
+            return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
+        }
 
-		if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
-			oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
-			// ranges have a vertical border in common
-			// make sure rows are identical:
-			return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
-		}
-		return false;
-   	}
-   	
-	/**
-	 * Create an enclosing CellRange for the two cell ranges.
-	 * 
-	 * @return enclosing CellRange
-	 */
-	public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
-		if( crB == null) {
-			return crA.copy();
-		}
-		
-		return
-			new CellRangeAddress(
-				lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
-				gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
-				lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
-				gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
-			);
-		
-	}
-	
-	/**
-	 * @return true if a < b
-	 */
-	private static boolean lt(int a, int b)
-	{
-		return a == -1 ? false : (b == -1 ? true : a < b);
-	}
-	
-	/**
-	 * @return true if a <= b
-	 */
-	private static boolean le(int a, int b)
-	{
-		return a == b || lt(a,b);
-	}
-	
-	/**
-	 * @return true if a > b
-	 */
-	private static boolean gt(int a, int b)
-	{
-		return lt(b,a);
-	}
+        if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
+                oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
+            // ranges have a vertical border in common
+            // make sure rows are identical:
+            return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
+        }
+        return false;
+    }
 
-	/**
-	 * @return true if a >= b
-	 */
-	private static boolean ge(int a, int b)
-	{
-		return !lt(a,b);
-	}
+    /**
+     * Create an enclosing CellRange for the two cell ranges.
+     * 
+     * @return enclosing CellRange
+     */
+    public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
+        if( crB == null) {
+            return crA.copy();
+        }
+
+        return new CellRangeAddress(
+                   lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
+                   gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
+                   lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
+                   gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
+        );
+    }
+
+    /**
+     * @return true if a < b
+     */
+    private static boolean lt(int a, int b)
+    {
+        return a == -1 ? false : (b == -1 ? true : a < b);
+    }
+
+    /**
+     * @return true if a <= b
+     */
+    private static boolean le(int a, int b)
+    {
+        return a == b || lt(a,b);
+    }
+
+    /**
+     * @return true if a > b
+     */
+    private static boolean gt(int a, int b)
+    {
+        return lt(b,a);
+    }
+
+    /**
+     * @return true if a >= b
+     */
+    private static boolean ge(int a, int b)
+    {
+        return !lt(a,b);
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
index be7aafa..59c49d8 100644
--- a/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
+++ b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
@@ -25,525 +25,523 @@
 
 /**
  * Font Formatting Block of the Conditional Formatting Rule Record.
- *
- * @author Dmitriy Kumshayev
  */
-public final class FontFormatting
-{
-	private byte[] _rawData;
+public final class FontFormatting {
+    private byte[] _rawData;
 
-	private static final int OFFSET_FONT_NAME = 0;
-	private static final int OFFSET_FONT_HEIGHT = 64;
-	private static final int OFFSET_FONT_OPTIONS = 68;
-	private static final int OFFSET_FONT_WEIGHT = 72;
-	private static final int OFFSET_ESCAPEMENT_TYPE = 74;
-	private static final int OFFSET_UNDERLINE_TYPE = 76;
-	private static final int OFFSET_FONT_COLOR_INDEX = 80;
-	private static final int OFFSET_OPTION_FLAGS = 88;
-	private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
-	private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
-	private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
-	private static final int OFFSET_NOT_USED1 = 104;
-	private static final int OFFSET_NOT_USED2 = 108;
-	private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes  0x7FFFFFFF at this offset
-	private static final int OFFSET_FONT_FORMATING_END = 116;
-	private static final int RAW_DATA_SIZE = 118;
+    private static final int OFFSET_FONT_NAME = 0;
+    private static final int OFFSET_FONT_HEIGHT = 64;
+    private static final int OFFSET_FONT_OPTIONS = 68;
+    private static final int OFFSET_FONT_WEIGHT = 72;
+    private static final int OFFSET_ESCAPEMENT_TYPE = 74;
+    private static final int OFFSET_UNDERLINE_TYPE = 76;
+    private static final int OFFSET_FONT_COLOR_INDEX = 80;
+    private static final int OFFSET_OPTION_FLAGS = 88;
+    private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
+    private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
+    private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
+    private static final int OFFSET_NOT_USED1 = 104;
+    private static final int OFFSET_NOT_USED2 = 108;
+    private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes  0x7FFFFFFF at this offset
+    private static final int OFFSET_FONT_FORMATING_END = 116;
+    private static final int RAW_DATA_SIZE = 118;
 
 
-	public final static int  FONT_CELL_HEIGHT_PRESERVED   = 0xFFFFFFFF;
+    public final static int  FONT_CELL_HEIGHT_PRESERVED   = 0xFFFFFFFF;
 
-	// FONT OPTIONS MASKS
-	private static final BitField posture       = BitFieldFactory.getInstance(0x00000002);
-	private static final BitField outline       = BitFieldFactory.getInstance(0x00000008);
-	private static final BitField shadow        = BitFieldFactory.getInstance(0x00000010);
-	private static final BitField cancellation	= BitFieldFactory.getInstance(0x00000080);
+    // FONT OPTIONS MASKS
+    private static final BitField posture       = BitFieldFactory.getInstance(0x00000002);
+    private static final BitField outline       = BitFieldFactory.getInstance(0x00000008);
+    private static final BitField shadow        = BitFieldFactory.getInstance(0x00000010);
+    private static final BitField cancellation	= BitFieldFactory.getInstance(0x00000080);
 
-	// OPTION FLAGS MASKS
+    // OPTION FLAGS MASKS
 
-	private static final BitField styleModified        = BitFieldFactory.getInstance(0x00000002);
-	private static final BitField outlineModified      = BitFieldFactory.getInstance(0x00000008);
-	private static final BitField shadowModified       = BitFieldFactory.getInstance(0x00000010);
-	private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
+    private static final BitField styleModified        = BitFieldFactory.getInstance(0x00000002);
+    private static final BitField outlineModified      = BitFieldFactory.getInstance(0x00000008);
+    private static final BitField shadowModified       = BitFieldFactory.getInstance(0x00000010);
+    private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
 
-	/** Escapement type - None */
-	public static final short SS_NONE  = 0;
-	/** Escapement type - Superscript */
-	public static final short SS_SUPER = 1;
-	/** Escapement type - Subscript */
-	public static final short SS_SUB   = 2;
-	/** Underline type - None */
-	public static final byte U_NONE               = 0;
-	/** Underline type - Single */
-	public static final byte U_SINGLE             = 1;
-	/** Underline type - Double */
-	public static final byte U_DOUBLE             = 2;
-	/** Underline type - Single Accounting */
-	public static final byte U_SINGLE_ACCOUNTING  = 0x21;
-	/** Underline type - Double Accounting */
-	public static final byte U_DOUBLE_ACCOUNTING  = 0x22;
-	/** Normal boldness (not bold) */
-	private static final short FONT_WEIGHT_NORMAL = 0x190;
+    /** Escapement type - None */
+    public static final short SS_NONE  = 0;
+    /** Escapement type - Superscript */
+    public static final short SS_SUPER = 1;
+    /** Escapement type - Subscript */
+    public static final short SS_SUB   = 2;
+    /** Underline type - None */
+    public static final byte U_NONE               = 0;
+    /** Underline type - Single */
+    public static final byte U_SINGLE             = 1;
+    /** Underline type - Double */
+    public static final byte U_DOUBLE             = 2;
+    /** Underline type - Single Accounting */
+    public static final byte U_SINGLE_ACCOUNTING  = 0x21;
+    /** Underline type - Double Accounting */
+    public static final byte U_DOUBLE_ACCOUNTING  = 0x22;
+    /** Normal boldness (not bold) */
+    private static final short FONT_WEIGHT_NORMAL = 0x190;
 
-	/**
-	 * Bold boldness (bold)
-	 */
-	private static final short FONT_WEIGHT_BOLD	 = 0x2bc;
+    /**
+     * Bold boldness (bold)
+     */
+    private static final short FONT_WEIGHT_BOLD	 = 0x2bc;
 
-	private FontFormatting(byte[] rawData) {
-		_rawData = rawData;
-	}
+    private FontFormatting(byte[] rawData) {
+        _rawData = rawData;
+    }
 
-	public FontFormatting()
-	{
-		this(new byte[RAW_DATA_SIZE]);
+    public FontFormatting()
+    {
+        this(new byte[RAW_DATA_SIZE]);
 
-		setFontHeight(-1);
-		setItalic(false);
-		setFontWieghtModified(false);
-		setOutline(false);
-		setShadow(false);
-		setStrikeout(false);
-		setEscapementType((short)0);
-		setUnderlineType((byte)0);
-		setFontColorIndex((short)-1);
+        setFontHeight(-1);
+        setItalic(false);
+        setFontWieghtModified(false);
+        setOutline(false);
+        setShadow(false);
+        setStrikeout(false);
+        setEscapementType((short)0);
+        setUnderlineType((byte)0);
+        setFontColorIndex((short)-1);
 
-		setFontStyleModified(false);
-		setFontOutlineModified(false);
-		setFontShadowModified(false);
-		setFontCancellationModified(false);
+        setFontStyleModified(false);
+        setFontOutlineModified(false);
+        setFontShadowModified(false);
+        setFontCancellationModified(false);
 
-		setEscapementTypeModified(false);
-		setUnderlineTypeModified(false);
+        setEscapementTypeModified(false);
+        setUnderlineTypeModified(false);
 
-		setShort(OFFSET_FONT_NAME, 0);
-		setInt(OFFSET_NOT_USED1, 0x00000001);
-		setInt(OFFSET_NOT_USED2, 0x00000000);
-		setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes  0x7FFFFFFF at this offset
-		setShort(OFFSET_FONT_FORMATING_END, 0x0001);
-	}
+        setShort(OFFSET_FONT_NAME, 0);
+        setInt(OFFSET_NOT_USED1, 0x00000001);
+        setInt(OFFSET_NOT_USED2, 0x00000000);
+        setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes  0x7FFFFFFF at this offset
+        setShort(OFFSET_FONT_FORMATING_END, 0x0001);
+    }
 
-	/** Creates new FontFormatting */
-	public FontFormatting(RecordInputStream in)
-	{
-		this(new byte[RAW_DATA_SIZE]);
-		for (int i = 0; i < _rawData.length; i++)
-		{
-			_rawData[i] = in.readByte();
-		}
-	}
+    /** Creates new FontFormatting */
+    public FontFormatting(RecordInputStream in)
+    {
+        this(new byte[RAW_DATA_SIZE]);
+        for (int i = 0; i < _rawData.length; i++)
+        {
+            _rawData[i] = in.readByte();
+        }
+    }
 
-	private short getShort(int offset) {
-		return LittleEndian.getShort( _rawData, offset);
-	}
-	private void setShort(int offset, int value) {
-		LittleEndian.putShort( _rawData, offset, (short)value);
-	}
-	private int getInt(int offset) {
-		return LittleEndian.getInt( _rawData, offset);
-	}
-	private void setInt(int offset, int value) {
-		LittleEndian.putInt( _rawData, offset, value);
-	}
+    private short getShort(int offset) {
+        return LittleEndian.getShort( _rawData, offset);
+    }
+    private void setShort(int offset, int value) {
+        LittleEndian.putShort( _rawData, offset, (short)value);
+    }
+    private int getInt(int offset) {
+        return LittleEndian.getInt( _rawData, offset);
+    }
+    private void setInt(int offset, int value) {
+        LittleEndian.putInt( _rawData, offset, value);
+    }
 
-	public byte[] getRawRecord()
-	{
-		return _rawData;
-	}
+    public byte[] getRawRecord()
+    {
+        return _rawData;
+    }
 
-	/**
-	 * sets the height of the font in 1/20th point units
-	 *
-	 *
-	 * @param height  fontheight (in points/20); or -1 to preserve the cell font height
-	 */
+    public int getDataLength() {
+        return RAW_DATA_SIZE;
+    }
 
-	public void setFontHeight(int height)
-	{
-		setInt(OFFSET_FONT_HEIGHT, height);
-	}
+    /**
+     * sets the height of the font in 1/20th point units
+     *
+     *
+     * @param height  fontheight (in points/20); or -1 to preserve the cell font height
+     */
 
-	/**
-	 * gets the height of the font in 1/20th point units
-	 *
-	 * @return fontheight (in points/20); or -1 if not modified
-	 */
-	public int getFontHeight()
-	{
-		return getInt(OFFSET_FONT_HEIGHT);
-	}
+    public void setFontHeight(int height)
+    {
+        setInt(OFFSET_FONT_HEIGHT, height);
+    }
 
-	private void setFontOption(boolean option, BitField field)
-	{
-		int options = getInt(OFFSET_FONT_OPTIONS);
-		options = field.setBoolean(options, option);
-		setInt(OFFSET_FONT_OPTIONS, options);
-	}
+    /**
+     * gets the height of the font in 1/20th point units
+     *
+     * @return fontheight (in points/20); or -1 if not modified
+     */
+    public int getFontHeight()
+    {
+        return getInt(OFFSET_FONT_HEIGHT);
+    }
 
-	private boolean getFontOption(BitField field)
-	{
-		int options = getInt(OFFSET_FONT_OPTIONS);
-		return field.isSet(options);
-	}
+    private void setFontOption(boolean option, BitField field)
+    {
+        int options = getInt(OFFSET_FONT_OPTIONS);
+        options = field.setBoolean(options, option);
+        setInt(OFFSET_FONT_OPTIONS, options);
+    }
 
-	/**
-	 * set the font to be italics or not
-	 *
-	 * @param italic - whether the font is italics or not
-	 * @see #setFontOption(boolean, org.apache.poi.util.BitField)
-	 */
+    private boolean getFontOption(BitField field)
+    {
+        int options = getInt(OFFSET_FONT_OPTIONS);
+        return field.isSet(options);
+    }
 
-	public void setItalic(boolean italic)
-	{
-		setFontOption(italic, posture);
-	}
+    /**
+     * set the font to be italics or not
+     *
+     * @param italic - whether the font is italics or not
+     * @see #setFontOption(boolean, org.apache.poi.util.BitField)
+     */
 
-	/**
-	 * get whether the font is to be italics or not
-	 *
-	 * @return italics - whether the font is italics or not
-	 * @see #getFontOption(org.apache.poi.util.BitField)
-	 */
+    public void setItalic(boolean italic)
+    {
+        setFontOption(italic, posture);
+    }
 
-	public boolean isItalic()
-	{
-		return getFontOption(posture);
-	}
+    /**
+     * get whether the font is to be italics or not
+     *
+     * @return italics - whether the font is italics or not
+     * @see #getFontOption(org.apache.poi.util.BitField)
+     */
 
-	public void setOutline(boolean on)
-	{
-		setFontOption(on, outline);
-	}
+    public boolean isItalic()
+    {
+        return getFontOption(posture);
+    }
 
-	public boolean isOutlineOn()
-	{
-		return getFontOption(outline);
-	}
+    public void setOutline(boolean on)
+    {
+        setFontOption(on, outline);
+    }
 
-	public void setShadow(boolean on)
-	{
-		setFontOption(on, shadow);
-	}
+    public boolean isOutlineOn()
+    {
+        return getFontOption(outline);
+    }
 
-	public boolean isShadowOn()
-	{
-		return getFontOption(shadow);
-	}
+    public void setShadow(boolean on)
+    {
+        setFontOption(on, shadow);
+    }
 
-	/**
-	 * set the font to be stricken out or not
-	 *
-	 * @param strike - whether the font is stricken out or not
-	 */
+    public boolean isShadowOn()
+    {
+        return getFontOption(shadow);
+    }
 
-	public void setStrikeout(boolean strike)
-	{
-		setFontOption(strike, cancellation);
-	}
+    /**
+     * set the font to be stricken out or not
+     *
+     * @param strike - whether the font is stricken out or not
+     */
+    public void setStrikeout(boolean strike)
+    {
+        setFontOption(strike, cancellation);
+    }
 
-	/**
-	 * get whether the font is to be stricken out or not
-	 *
-	 * @return strike - whether the font is stricken out or not
-	 * @see #getFontOption(org.apache.poi.util.BitField)
-	 */
+    /**
+     * get whether the font is to be stricken out or not
+     *
+     * @return strike - whether the font is stricken out or not
+     * @see #getFontOption(org.apache.poi.util.BitField)
+     */
+    public boolean isStruckout()
+    {
+        return getFontOption(cancellation);
+    }
 
-	public boolean isStruckout()
-	{
-		return getFontOption(cancellation);
-	}
+    /**
+     * set the font weight (100-1000dec or 0x64-0x3e8).  Default is
+     * 0x190 for normal and 0x2bc for bold
+     *
+     * @param bw - a number between 100-1000 for the fonts "boldness"
+     */
 
-	/**
-	 * set the font weight (100-1000dec or 0x64-0x3e8).  Default is
-	 * 0x190 for normal and 0x2bc for bold
-	 *
-	 * @param bw - a number between 100-1000 for the fonts "boldness"
-	 */
+    private void setFontWeight(short pbw)
+    {
+        short bw = pbw;
+        if( bw<100) { bw=100; }
+        if( bw>1000){ bw=1000; }
+        setShort(OFFSET_FONT_WEIGHT, bw);
+    }
 
-	private void setFontWeight(short pbw)
-	{
-		short bw = pbw;
-		if( bw<100) { bw=100; }
-		if( bw>1000){ bw=1000; }
-		setShort(OFFSET_FONT_WEIGHT, bw);
-	}
+    /**
+     * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
+     *
+     * @param bold - set font weight to bold if true; to normal otherwise
+     */
+    public void setBold(boolean bold)
+    {
+        setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
+    }
 
-	/**
-	 * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
-	 *
-	 * @param bold - set font weight to bold if true; to normal otherwise
-	 */
-	public void setBold(boolean bold)
-	{
-		setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
-	}
+    /**
+     * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
+     * 0x190 for normal and 0x2bc for bold
+     *
+     * @return bw - a number between 100-1000 for the fonts "boldness"
+     */
 
-	/**
-	 * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
-	 * 0x190 for normal and 0x2bc for bold
-	 *
-	 * @return bw - a number between 100-1000 for the fonts "boldness"
-	 */
+    public short getFontWeight()
+    {
+        return getShort(OFFSET_FONT_WEIGHT);
+    }
 
-	public short getFontWeight()
-	{
-		return getShort(OFFSET_FONT_WEIGHT);
-	}
-
-	/**
-	 * get whether the font weight is set to bold or not
-	 *
-	 * @return bold - whether the font is bold or not
-	 */
-
-	public boolean isBold()
-	{
-		return getFontWeight()==FONT_WEIGHT_BOLD;
-	}
+    /**
+     * get whether the font weight is set to bold or not
+     *
+     * @return bold - whether the font is bold or not
+     */
 
-	/**
-	 * get the type of super or subscript for the font
-	 *
-	 * @return super or subscript option
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
-	 */
-	public short getEscapementType()
-	{
-		return getShort(OFFSET_ESCAPEMENT_TYPE);
-	}
+    public boolean isBold()
+    {
+        return getFontWeight()==FONT_WEIGHT_BOLD;
+    }
 
-	/**
-	 * set the escapement type for the font
-	 *
-	 * @param escapementType  super or subscript option
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
-	 */
-	public void setEscapementType( short escapementType)
-	{
-		setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
-	}
+    /**
+     * get the type of super or subscript for the font
+     *
+     * @return super or subscript option
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+     */
+    public short getEscapementType()
+    {
+        return getShort(OFFSET_ESCAPEMENT_TYPE);
+    }
 
-	/**
-	 * get the type of underlining for the font
-	 *
-	 * @return font underlining type
-	 *
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
-	 */
+    /**
+     * set the escapement type for the font
+     *
+     * @param escapementType  super or subscript option
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+     */
+    public void setEscapementType( short escapementType)
+    {
+        setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
+    }
 
-	public short getUnderlineType()
-	{
-		return getShort(OFFSET_UNDERLINE_TYPE);
-	}
+    /**
+     * get the type of underlining for the font
+     *
+     * @return font underlining type
+     *
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+     */
+    public short getUnderlineType()
+    {
+        return getShort(OFFSET_UNDERLINE_TYPE);
+    }
 
-	/**
-	 * set the type of underlining type for the font
-	 *
-	 * @param underlineType underline option
-	 *
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
-	 */
-	public void setUnderlineType( short underlineType)
-	{
-		setShort(OFFSET_UNDERLINE_TYPE, underlineType);
-	}
+    /**
+     * set the type of underlining type for the font
+     *
+     * @param underlineType underline option
+     *
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+     */
+    public void setUnderlineType( short underlineType)
+    {
+        setShort(OFFSET_UNDERLINE_TYPE, underlineType);
+    }
 
 
-	public short getFontColorIndex()
-	{
-		return (short)getInt(OFFSET_FONT_COLOR_INDEX);
-	}
+    public short getFontColorIndex()
+    {
+        return (short)getInt(OFFSET_FONT_COLOR_INDEX);
+    }
 
-	public void setFontColorIndex(short fci )
-	{
-		setInt(OFFSET_FONT_COLOR_INDEX,fci);
-	}
+    public void setFontColorIndex(short fci )
+    {
+        setInt(OFFSET_FONT_COLOR_INDEX,fci);
+    }
 
-	private boolean getOptionFlag(BitField field)
-	{
-		int optionFlags = getInt(OFFSET_OPTION_FLAGS);
-		int value = field.getValue(optionFlags);
-		return value==0? true : false ;
-	}
+    private boolean getOptionFlag(BitField field) {
+        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
+        int value = field.getValue(optionFlags);
+        return value==0? true : false ;
+    }
 
-	private void setOptionFlag(boolean modified, BitField field)
-	{
-		int value = modified? 0 : 1;
-		int optionFlags = getInt(OFFSET_OPTION_FLAGS);
-		optionFlags = field.setValue(optionFlags, value);
-		setInt(OFFSET_OPTION_FLAGS, optionFlags);
-	}
+    private void setOptionFlag(boolean modified, BitField field)
+    {
+        int value = modified? 0 : 1;
+        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
+        optionFlags = field.setValue(optionFlags, value);
+        setInt(OFFSET_OPTION_FLAGS, optionFlags);
+    }
 
 
-	public boolean isFontStyleModified()
-	{
-		return getOptionFlag(styleModified);
-	}
+    public boolean isFontStyleModified()
+    {
+        return getOptionFlag(styleModified);
+    }
 
 
-	public void setFontStyleModified(boolean modified)
-	{
-		setOptionFlag(modified, styleModified);
-	}
+    public void setFontStyleModified(boolean modified)
+    {
+        setOptionFlag(modified, styleModified);
+    }
 
-	public boolean isFontOutlineModified()
-	{
-		return getOptionFlag(outlineModified);
-	}
+    public boolean isFontOutlineModified()
+    {
+        return getOptionFlag(outlineModified);
+    }
 
-	public void setFontOutlineModified(boolean modified)
-	{
-		setOptionFlag(modified, outlineModified);
-	}
+    public void setFontOutlineModified(boolean modified)
+    {
+        setOptionFlag(modified, outlineModified);
+    }
 
-	public boolean isFontShadowModified()
-	{
-		return getOptionFlag(shadowModified);
-	}
+    public boolean isFontShadowModified()
+    {
+        return getOptionFlag(shadowModified);
+    }
 
-	public void setFontShadowModified(boolean modified)
-	{
-		setOptionFlag(modified, shadowModified);
-	}
-	public void setFontCancellationModified(boolean modified)
-	{
-		setOptionFlag(modified, cancellationModified);
-	}
+    public void setFontShadowModified(boolean modified)
+    {
+        setOptionFlag(modified, shadowModified);
+    }
+    public void setFontCancellationModified(boolean modified)
+    {
+        setOptionFlag(modified, cancellationModified);
+    }
 
-	public boolean isFontCancellationModified()
-	{
-		return getOptionFlag(cancellationModified);
-	}
+    public boolean isFontCancellationModified()
+    {
+        return getOptionFlag(cancellationModified);
+    }
 
-	public void setEscapementTypeModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
-	}
-	public boolean isEscapementTypeModified()
-	{
-		int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
-		return escapementModified == 0;
-	}
+    public void setEscapementTypeModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
+    }
+    public boolean isEscapementTypeModified()
+    {
+        int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
+        return escapementModified == 0;
+    }
 
-	public void setUnderlineTypeModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
-	}
+    public void setUnderlineTypeModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
+    }
 
-	public boolean isUnderlineTypeModified()
-	{
-		int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
-		return underlineModified == 0;
-	}
+    public boolean isUnderlineTypeModified()
+    {
+        int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
+        return underlineModified == 0;
+    }
 
-	public void setFontWieghtModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
-	}
+    public void setFontWieghtModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
+    }
 
-	public boolean isFontWeightModified()
-	{
-		int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
-		return fontStyleModified == 0;
-	}
+    public boolean isFontWeightModified()
+    {
+        int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
+        return fontStyleModified == 0;
+    }
 
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-		buffer.append("	[Font Formatting]\n");
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("	[Font Formatting]\n");
 
-		buffer.append("	.font height = ").append(getFontHeight()).append(" twips\n");
+        buffer.append("	.font height = ").append(getFontHeight()).append(" twips\n");
 
-		if( isFontStyleModified() )
-		{
-			buffer.append("	.font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
-		}
-		else
-		{
-			buffer.append("	.font posture = ]not modified]").append("\n");
-		}
+        if( isFontStyleModified() )
+        {
+            buffer.append("	.font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
+        }
+        else
+        {
+            buffer.append("	.font posture = ]not modified]").append("\n");
+        }
 
-		if( isFontOutlineModified() )
-		{
-			buffer.append("	.font outline = ").append(isOutlineOn()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font outline is not modified\n");
-		}
+        if( isFontOutlineModified() )
+        {
+            buffer.append("	.font outline = ").append(isOutlineOn()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font outline is not modified\n");
+        }
 
-		if( isFontShadowModified() )
-		{
-			buffer.append("	.font shadow = ").append(isShadowOn()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font shadow is not modified\n");
-		}
+        if( isFontShadowModified() )
+        {
+            buffer.append("	.font shadow = ").append(isShadowOn()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font shadow is not modified\n");
+        }
 
-		if( isFontCancellationModified() )
-		{
-			buffer.append("	.font strikeout = ").append(isStruckout()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font strikeout is not modified\n");
-		}
+        if( isFontCancellationModified() )
+        {
+            buffer.append("	.font strikeout = ").append(isStruckout()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font strikeout is not modified\n");
+        }
 
-		if( isFontStyleModified() )
-		{
-			buffer.append("	.font weight = ").
-				append(getFontWeight()).
-				append(
-					getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
-							: getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" : "0x"+Integer.toHexString(getFontWeight())).
-				append("\n");
-		}
-		else
-		{
-			buffer.append("	.font weight = ]not modified]").append("\n");
-		}
+        if( isFontStyleModified() )
+        {
+            buffer.append("	.font weight = ").
+            append(getFontWeight()).
+            append(
+                    getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
+                    : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" 
+                    : "0x"+Integer.toHexString(getFontWeight())).
+            append("\n");
+        }
+        else
+        {
+            buffer.append("	.font weight = ]not modified]").append("\n");
+        }
 
-		if( isEscapementTypeModified() )
-		{
-			buffer.append("	.escapement type = ").append(getEscapementType()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.escapement type is not modified\n");
-		}
+        if( isEscapementTypeModified() )
+        {
+            buffer.append("	.escapement type = ").append(getEscapementType()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.escapement type is not modified\n");
+        }
 
-		if( isUnderlineTypeModified() )
-		{
-			buffer.append("	.underline type = ").append(getUnderlineType()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.underline type is not modified\n");
-		}
-		buffer.append("	.color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
+        if( isUnderlineTypeModified() )
+        {
+            buffer.append("	.underline type = ").append(getUnderlineType()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.underline type is not modified\n");
+        }
+        buffer.append("	.color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
 
-		buffer.append("	[/Font Formatting]\n");
-		return buffer.toString();
-	}
+        buffer.append("	[/Font Formatting]\n");
+        return buffer.toString();
+    }
 
-	public Object clone()
-	{
-		byte[] rawData = _rawData.clone();
-		return new FontFormatting(rawData);
-	}
+    public Object clone()
+    {
+        byte[] rawData = _rawData.clone();
+        return new FontFormatting(rawData);
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java b/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java
new file mode 100644
index 0000000..f405c03
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/cf/IconMultiStateFormatting.java
@@ -0,0 +1,139 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Icon / Multi-State Conditional Formatting Rule Record.
+ */
+public final class IconMultiStateFormatting implements Cloneable {
+    private static POILogger log = POILogFactory.getLogger(IconMultiStateFormatting.class);
+            
+    private IconSet iconSet;
+    private byte options;
+    private Threshold[] thresholds;
+    
+    private static BitField iconOnly = BitFieldFactory.getInstance(0x01);
+    private static BitField reversed = BitFieldFactory.getInstance(0x04);
+
+    public IconMultiStateFormatting() {
+        iconSet = IconSet.GYR_3_TRAFFIC_LIGHTS;
+        options = 0;
+        thresholds = new Threshold[iconSet.num];
+    }
+    public IconMultiStateFormatting(LittleEndianInput in) {
+        in.readShort(); // Ignored
+        in.readByte();  // Reserved
+        int num = in.readByte();
+        int set = in.readByte();
+        iconSet = IconSet.byId(set);
+        if (iconSet.num != num) {
+            log.log(POILogger.WARN, "Inconsistent Icon Set defintion, found " + iconSet + " but defined as " + num + " entries");
+        }
+        options = in.readByte();
+        
+        thresholds = new Threshold[iconSet.num];
+        for (int i=0; i<thresholds.length; i++) {
+            thresholds[i] = new Threshold(in);
+        }
+    }
+    
+    public IconSet getIconSet() {
+        return iconSet;
+    }
+    public void setIconSet(IconSet set) {
+        this.iconSet = set;
+    }
+
+    public Threshold[] getThresholds() {
+        return thresholds;
+    }
+    public void setThresholds(Threshold[] thresholds) {
+        this.thresholds = thresholds;
+    }
+    
+    public boolean isIconOnly() {
+        return getOptionFlag(iconOnly);
+    }
+    public void setIconOnly(boolean only) {
+        setOptionFlag(only, iconOnly);
+    }
+    
+    public boolean isReversed() {
+        return getOptionFlag(reversed);
+    }
+    public void setReversed(boolean rev) {
+        setOptionFlag(rev, reversed);
+    }
+    
+    private boolean getOptionFlag(BitField field) {
+        int value = field.getValue(options);
+        return value==0 ? false : true;
+    }
+    private void setOptionFlag(boolean option, BitField field) {
+        options = field.setByteBoolean(options, option);
+    }
+    
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("    [Icon Formatting]\n");
+        buffer.append("          .icon_set = ").append(iconSet).append("\n");
+        buffer.append("          .icon_only= ").append(isIconOnly()).append("\n");
+        buffer.append("          .reversed = ").append(isReversed()).append("\n");
+        for (Threshold t : thresholds) {
+            buffer.append(t.toString());
+        }
+        buffer.append("    [/Icon Formatting]\n");
+        return buffer.toString();
+    }
+    
+    public Object clone()  {
+      IconMultiStateFormatting rec = new IconMultiStateFormatting();
+      rec.iconSet = iconSet;
+      rec.options = options;
+      rec.thresholds = new Threshold[thresholds.length];
+      System.arraycopy(thresholds, 0, rec.thresholds, 0, thresholds.length);
+      return rec;
+    }
+    
+    public int getDataLength() {
+        int len = 6;
+        for (Threshold t : thresholds) {
+            len += t.getDataLength();
+        }
+        return len;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(0);
+        out.writeByte(0);
+        out.writeByte(iconSet.num);
+        out.writeByte(iconSet.id);
+        out.writeByte(options);
+        for (Threshold t : thresholds) {
+            t.serialize(out);
+        }
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java b/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
index 2587157..3e18eac 100644
--- a/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
+++ b/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
@@ -24,8 +24,6 @@
 
 /**
  * Pattern Formatting Block of the Conditional Formatting Rule Record.
- * 
- * @author Dmitriy Kumshayev
  */
 public final class PatternFormatting implements Cloneable {
     /**  No background */
@@ -89,6 +87,10 @@
         field_16_pattern_color_indexes    = in.readUShort();
     }
     
+    public int getDataLength() {
+        return 4;
+    }
+    
     /**
      * setting fill pattern
      *
diff --git a/src/java/org/apache/poi/hssf/record/cf/Threshold.java b/src/java/org/apache/poi/hssf/record/cf/Threshold.java
new file mode 100644
index 0000000..4620278
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/cf/Threshold.java
@@ -0,0 +1,146 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import java.util.Arrays;
+
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Threshold / value for changes in Conditional Formatting
+ */
+public final class Threshold {
+    /**
+     * Cell values that are equal to the threshold value do not pass the threshold
+     */
+    public static final byte EQUALS_EXCLUDE = 0;
+    /**
+     * Cell values that are equal to the threshold value pass the threshold.
+     */
+    public static final byte EQUALS_INCLUDE = 1;
+    
+    private byte type;
+    private Formula formula;
+    private Double value;
+    private byte equals;
+
+    public Threshold() {
+        type = (byte)RangeType.NUMBER.id;
+        formula = Formula.create(null);
+        value = 0d;
+    }
+
+    /** Creates new Threshold */
+    public Threshold(LittleEndianInput in) {
+        type = in.readByte();
+        short formulaLen = in.readShort();
+        if (formulaLen > 0) {
+            formula = Formula.read(formulaLen, in);
+        } else {
+            formula = Formula.create(null);
+        }
+        // Value is only there for non-formula, non min/max thresholds
+        if (formulaLen == 0 && type != RangeType.MIN.id &&
+                type != RangeType.MAX.id) {
+            value = in.readDouble();
+        }
+        equals = in.readByte();
+        // Reserved, 4 bytes, all 0
+        in.readInt();
+    }
+
+    public byte getType() {
+        return type;
+    }
+    public void setType(byte type) {
+        this.type = type;
+    }
+    public void setType(int type) {
+        this.type = (byte)type;
+    }
+
+    protected Formula getFormula() {
+        return formula;
+    }
+    public Ptg[] getParsedExpression() {
+        return formula.getTokens();
+    }
+    public void setParsedExpression(Ptg[] ptgs) {
+        formula = Formula.create(ptgs);
+    }
+
+    public Double getValue() {
+        return value;
+    }
+    public void setValue(Double value) {
+        this.value = value;
+    }
+    
+    public byte getEquals() {
+        return equals;
+    }
+    public void setEquals(byte equals) {
+        this.equals = equals;
+    }
+
+    public int getDataLength() {
+        int len = 1 + formula.getEncodedSize();
+        if (value != null) {
+            len += 8;
+        }
+        len += 5;
+        return len;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("    [CF Threshold]\n");
+        buffer.append("          .type    = ").append(Integer.toHexString(type)).append("\n");
+        buffer.append("          .formula = ").append(Arrays.toString(formula.getTokens())).append("\n");
+        buffer.append("          .value   = ").append(value).append("\n");
+        buffer.append("    [/CF Threshold]\n");
+        return buffer.toString();
+    }
+
+    public Object clone() {
+      Threshold rec = new Threshold();
+      rec.type = type;
+      rec.formula = formula;
+      rec.value = value;
+      rec.equals = equals;
+      return rec;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeByte(type);
+        if (formula.getTokens().length == 0) {
+            out.writeShort(0);
+        } else {
+            formula.serialize(out);
+        }
+        if (value != null) {
+            out.writeDouble(value);
+        }
+        out.writeByte(equals);
+        out.writeInt(0); // Reserved
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/record/common/FtrHeader.java b/src/java/org/apache/poi/hssf/record/common/FtrHeader.java
index dc2d4e2..dba24f0 100644
--- a/src/java/org/apache/poi/hssf/record/common/FtrHeader.java
+++ b/src/java/org/apache/poi/hssf/record/common/FtrHeader.java
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.record.common;
 
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -28,62 +29,69 @@
  *  beyond those of a traditional record. 
  */
 public final class FtrHeader {
-	/** This MUST match the type on the containing record */
-	private short recordType;
-	/** This is a FrtFlags */
-	private short grbitFrt;
-	/** MUST be 8 bytes and all zero */
-	private byte[] reserved;
+    /** This MUST match the type on the containing record */
+    private short recordType;
+    /** This is a FrtFlags */
+    private short grbitFrt;
+    /** The range of cells the parent record applies to, or 0 if N/A */
+    private CellRangeAddress associatedRange;
 
-	public FtrHeader() {
-		reserved = new byte[8];
-	}
+    public FtrHeader() {
+        associatedRange = new CellRangeAddress(0, 0, 0, 0);
+    }
 
-	public FtrHeader(RecordInputStream in) {
-		recordType = in.readShort();
-		grbitFrt   = in.readShort();
-		
-		reserved = new byte[8];
-		in.read(reserved, 0, 8);
-	}
+    public FtrHeader(RecordInputStream in) {
+        recordType = in.readShort();
+        grbitFrt   = in.readShort();
 
-	public String toString() {
-		StringBuffer buffer = new StringBuffer();
-		buffer.append(" [FUTURE HEADER]\n");
-		buffer.append("   Type " + recordType);
-		buffer.append("   Flags " + grbitFrt);
-		buffer.append(" [/FUTURE HEADER]\n");
-		return buffer.toString();
-	}
+        associatedRange = new CellRangeAddress(in);
+    }
 
-	public void serialize(LittleEndianOutput out) {
-		out.writeShort(recordType);
-		out.writeShort(grbitFrt);
-		out.write(reserved);
-	}
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(" [FUTURE HEADER]\n");
+        buffer.append("   Type " + recordType);
+        buffer.append("   Flags " + grbitFrt);
+        buffer.append(" [/FUTURE HEADER]\n");
+        return buffer.toString();
+    }
 
-	public static int getDataSize() {
-		return 12;
-	}
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(recordType);
+        out.writeShort(grbitFrt);
+        associatedRange.serialize(out);
+    }
 
-	public short getRecordType() {
-		return recordType;
-	}
-	public void setRecordType(short recordType) {
-		this.recordType = recordType;
-	}
+    public static int getDataSize() {
+        return 12;
+    }
 
-	public short getGrbitFrt() {
-		return grbitFrt;
-	}
-	public void setGrbitFrt(short grbitFrt) {
-		this.grbitFrt = grbitFrt;
-	}
+    public short getRecordType() {
+        return recordType;
+    }
+    public void setRecordType(short recordType) {
+        this.recordType = recordType;
+    }
 
-	public byte[] getReserved() {
-		return reserved;
-	}
-	public void setReserved(byte[] reserved) {
-		this.reserved = reserved;
-	}
+    public short getGrbitFrt() {
+        return grbitFrt;
+    }
+    public void setGrbitFrt(short grbitFrt) {
+        this.grbitFrt = grbitFrt;
+    }
+
+    public CellRangeAddress getAssociatedRange() {
+        return associatedRange;
+    }
+    public void setAssociatedRange(CellRangeAddress associatedRange) {
+        this.associatedRange = associatedRange;
+    }
+
+    public Object clone() {
+        FtrHeader result = new FtrHeader();
+        result.recordType = recordType;
+        result.grbitFrt = grbitFrt;
+        result.associatedRange = associatedRange.copy();
+        return result;
+    }
 }
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/java/org/apache/poi/hssf/record/common/FutureRecord.java
similarity index 70%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to src/java/org/apache/poi/hssf/record/common/FutureRecord.java
index 48744ec..65a26cc 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/java/org/apache/poi/hssf/record/common/FutureRecord.java
@@ -1,22 +1,30 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

-

-       http://www.apache.org/licenses/LICENSE-2.0

-

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

-

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.common;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+
+/**
+ * Title: Future Record, a newer (largely Excel 2007+) record
+ *  which contains a Future Record Header ({@link FtrHeader})
+ */
+public interface FutureRecord {
+    public short getFutureRecordType();
+    public FtrHeader getFutureHeader();
+    public CellRangeAddress getAssociatedRange();
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java b/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java
index f52a15d..564174b 100644
--- a/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java
+++ b/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java
@@ -95,7 +95,7 @@
 
 
 	public int readUByte() {
-		return _cipher.xorByte(_le.readUByte());
+		return readByte() & 0xFF;
 	}
 	public byte readByte() {
 		return (byte) _cipher.xorByte(_le.readUByte());
@@ -103,7 +103,7 @@
 
 
 	public int readUShort() {
-		return _cipher.xorShort(_le.readUShort());
+		return readShort() & 0xFFFF;
 	}
 	public short readShort() {
 		return (short) _cipher.xorShort(_le.readUShort());
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
index 0e2cb9d..c5c9964 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
@@ -17,196 +17,246 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Color;
 
 /**
  * High level representation for Border Formatting component
  * of Conditional Formatting settings
  */
-public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting
-{
-	private final CFRuleRecord cfRuleRecord;
-	private final BorderFormatting borderFormatting;
-	
-	protected HSSFBorderFormatting(CFRuleRecord cfRuleRecord)
-	{
-		this.cfRuleRecord = cfRuleRecord;
-		this.borderFormatting = cfRuleRecord.getBorderFormatting();
-	}
+public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting {
+    private final HSSFWorkbook workbook;
+    private final CFRuleBase cfRuleRecord;
+    private final BorderFormatting borderFormatting;
 
-	protected BorderFormatting getBorderFormattingBlock()
-	{
-		return borderFormatting;
-	}
+    protected HSSFBorderFormatting(CFRuleBase cfRuleRecord, HSSFWorkbook workbook) {
+        this.workbook = workbook;
+        this.cfRuleRecord = cfRuleRecord;
+        this.borderFormatting = cfRuleRecord.getBorderFormatting();
+    }
 
-	public short getBorderBottom()
-	{
-		return (short)borderFormatting.getBorderBottom();
-	}
+    protected BorderFormatting getBorderFormattingBlock() {
+        return borderFormatting;
+    }
 
-	public short getBorderDiagonal()
-	{
-		return (short)borderFormatting.getBorderDiagonal();
-	}
+    public short getBorderBottom() {
+        return (short)borderFormatting.getBorderBottom();
+    }
 
-	public short getBorderLeft()
-	{
-		return (short)borderFormatting.getBorderLeft();
-	}
+    public short getBorderDiagonal() {
+        return (short)borderFormatting.getBorderDiagonal();
+    }
 
-	public short getBorderRight()
-	{
-		return (short)borderFormatting.getBorderRight();
-	}
+    public short getBorderLeft() {
+        return (short)borderFormatting.getBorderLeft();
+    }
 
-	public short getBorderTop()
-	{
-		return (short)borderFormatting.getBorderTop();
-	}
+    public short getBorderRight() {
+        return (short)borderFormatting.getBorderRight();
+    }
 
-	public short getBottomBorderColor()
-	{
-		return (short)borderFormatting.getBottomBorderColor();
-	}
+    public short getBorderTop() {
+        return (short)borderFormatting.getBorderTop();
+    }
 
-	public short getDiagonalBorderColor()
-	{
-		return (short)borderFormatting.getDiagonalBorderColor();
-	}
+    public short getBottomBorderColor() {
+        return (short)borderFormatting.getBottomBorderColor();
+    }
+    public HSSFColor getBottomBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getBottomBorderColor()
+        );
+    }
 
-	public short getLeftBorderColor()
-	{
-		return (short)borderFormatting.getLeftBorderColor();
-	}
+    public short getDiagonalBorderColor() {
+        return (short)borderFormatting.getDiagonalBorderColor();
+    }
+    public HSSFColor getDiagonalBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getDiagonalBorderColor()
+        );
+    }
 
-	public short getRightBorderColor()
-	{
-		return (short)borderFormatting.getRightBorderColor();
-	}
+    public short getLeftBorderColor() {
+        return (short)borderFormatting.getLeftBorderColor();
+    }
+    public HSSFColor getLeftBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getLeftBorderColor()
+        );
+    }
 
-	public short getTopBorderColor()
-	{
-		return (short)borderFormatting.getTopBorderColor();
-	}
+    public short getRightBorderColor() {
+        return (short)borderFormatting.getRightBorderColor();
+    }
+    public HSSFColor getRightBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getRightBorderColor()
+        );
+    }
 
-	public boolean isBackwardDiagonalOn()
-	{
-		return borderFormatting.isBackwardDiagonalOn();
-	}
+    public short getTopBorderColor() {
+        return (short)borderFormatting.getTopBorderColor();
+    }
+    public HSSFColor getTopBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getTopBorderColor()
+        );
+    }
 
-	public boolean isForwardDiagonalOn()
-	{
-		return borderFormatting.isForwardDiagonalOn();
-	}
+    public boolean isBackwardDiagonalOn() {
+        return borderFormatting.isBackwardDiagonalOn();
+    }
+    public boolean isForwardDiagonalOn() {
+        return borderFormatting.isForwardDiagonalOn();
+    }
 
-	public void setBackwardDiagonalOn(boolean on)
-	{
-		borderFormatting.setBackwardDiagonalOn(on);
-		if( on )
-		{
-			cfRuleRecord.setTopLeftBottomRightBorderModified(on);
-		}
-	}
+    public void setBackwardDiagonalOn(boolean on) {
+        borderFormatting.setBackwardDiagonalOn(on);
+        if (on) {
+            cfRuleRecord.setTopLeftBottomRightBorderModified(on);
+        }
+    }
+    public void setForwardDiagonalOn(boolean on) {
+        borderFormatting.setForwardDiagonalOn(on);
+        if (on) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(on);
+        }
+    }
 
-	public void setBorderBottom(short border)
-	{
-		borderFormatting.setBorderBottom(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setBottomBorderModified(true);
-		}
-	}
+    public void setBorderBottom(short border) {
+        borderFormatting.setBorderBottom(border);
+        if (border != 0) {
+            cfRuleRecord.setBottomBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomBorderModified(false);
+        }
+    }
 
-	public void setBorderDiagonal(short border)
-	{
-		borderFormatting.setBorderDiagonal(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(true);
-			cfRuleRecord.setTopLeftBottomRightBorderModified(true);
-		}
-	}
+    public void setBorderDiagonal(short border) {
+        borderFormatting.setBorderDiagonal(border);
+        if (border != 0) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(true);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(false);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(false);
+        }
+    }
 
-	public void setBorderLeft(short border)
-	{
-		borderFormatting.setBorderLeft(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setLeftBorderModified(true);
-		}
-	}
+    public void setBorderLeft(short border) {
+        borderFormatting.setBorderLeft(border);
+        if (border != 0) {
+            cfRuleRecord.setLeftBorderModified(true);
+        } else {
+            cfRuleRecord.setLeftBorderModified(false);
+        }
+    }
 
-	public void setBorderRight(short border)
-	{
-		borderFormatting.setBorderRight(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setRightBorderModified(true);
-		}
-	}
+    public void setBorderRight(short border) {
+        borderFormatting.setBorderRight(border);
+        if (border != 0) {
+            cfRuleRecord.setRightBorderModified(true);
+        } else {
+            cfRuleRecord.setRightBorderModified(false);
+        }
+    }
 
-	public void setBorderTop(short border)
-	{
-		borderFormatting.setBorderTop(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setTopBorderModified(true);
-		}
-	}
+    public void setBorderTop(short border) {
+        borderFormatting.setBorderTop(border);
+        if (border != 0) {
+            cfRuleRecord.setTopBorderModified(true);
+        } else {
+            cfRuleRecord.setTopBorderModified(false);
+        }
+    }
 
-	public void setBottomBorderColor(short color)
-	{
-		borderFormatting.setBottomBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setBottomBorderModified(true);
-		}
-	}
+    public void setBottomBorderColor(short color) {
+        borderFormatting.setBottomBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setBottomBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomBorderModified(false);
+        }
+    }
+    public void setBottomBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setBottomBorderColor((short)0);
+        } else {
+            setBottomBorderColor(hcolor.getIndex());
+        }
+    }
 
-	public void setDiagonalBorderColor(short color)
-	{
-		borderFormatting.setDiagonalBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(true);
-			cfRuleRecord.setTopLeftBottomRightBorderModified(true);
-		}
-	}
+    public void setDiagonalBorderColor(short color) {
+        borderFormatting.setDiagonalBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(true);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(false);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(false);
+        }
+    }
+    public void setDiagonalBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setDiagonalBorderColor((short)0);
+        } else {
+            setDiagonalBorderColor(hcolor.getIndex());
+        }
+    }
 
-	public void setForwardDiagonalOn(boolean on)
-	{
-		borderFormatting.setForwardDiagonalOn(on);
-		if( on )
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(on);
-		}
-	}
+    public void setLeftBorderColor(short color) {
+        borderFormatting.setLeftBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setLeftBorderModified(true);
+        } else {
+            cfRuleRecord.setLeftBorderModified(false);
+        }
+    }
+    public void setLeftBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setLeftBorderColor((short)0);
+        } else {
+            setLeftBorderColor(hcolor.getIndex());
+        }
+    }
 
-	public void setLeftBorderColor(short color)
-	{
-		borderFormatting.setLeftBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setLeftBorderModified(true);
-		}
-	}
+    public void setRightBorderColor(short color) {
+        borderFormatting.setRightBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setRightBorderModified(true);
+        } else {
+            cfRuleRecord.setRightBorderModified(false);
+        }
+    }
+    public void setRightBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setRightBorderColor((short)0);
+        } else {
+            setRightBorderColor(hcolor.getIndex());
+        }
+    }
 
-	public void setRightBorderColor(short color)
-	{
-		borderFormatting.setRightBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setRightBorderModified(true);
-		}
-	}
-
-	public void setTopBorderColor(short color)
-	{
-		borderFormatting.setTopBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setTopBorderModified(true);
-		}
-	}
+    public void setTopBorderColor(short color) {
+        borderFormatting.setTopBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setTopBorderModified(true);
+        } else {
+            cfRuleRecord.setTopBorderModified(false);
+        }
+    }
+    public void setTopBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setTopBorderColor((short)0);
+        } else {
+            setTopBorderColor(hcolor.getIndex());
+        }
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index e5de299..b1e8b7a 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -538,18 +538,17 @@
 
     public void setCellValue(RichTextString value)
     {
-        HSSFRichTextString hvalue = (HSSFRichTextString) value;
         int row=_record.getRow();
         short col=_record.getColumn();
         short styleIndex=_record.getXFIndex();
-        if (hvalue == null)
+        if (value == null)
         {
             notifyFormulaChanging();
             setCellType(CELL_TYPE_BLANK, false, row, col, styleIndex);
             return;
         }
 
-        if(hvalue.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){
+        if(value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){
             throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
         }
 
@@ -557,7 +556,7 @@
             // Set the 'pre-evaluated result' for the formula
             // note - formulas do not preserve text formatting.
             FormulaRecordAggregate fr = (FormulaRecordAggregate) _record;
-            fr.setCachedStringResult(hvalue.getString());
+            fr.setCachedStringResult(value.getString());
             // Update our local cache to the un-formatted version
             _stringValue = new HSSFRichTextString(value.getString());
 
@@ -573,6 +572,7 @@
         }
         int index = 0;
 
+        HSSFRichTextString hvalue = (HSSFRichTextString) value;
         UnicodeString str = hvalue.getUnicodeString();
         index = _book.getWorkbook().addSSTString(str);
         (( LabelSSTRecord ) _record).setSSTIndex(index);
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
index 81de3a4..4e71ac2 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
@@ -129,10 +129,13 @@
 
     @Override
     void setShapeId(int shapeId) {
+    	if(shapeId > 65535) {
+    		throw new IllegalArgumentException("Cannot add more than " + 65535 + " shapes");
+    	}
         super.setShapeId(shapeId);
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
-        cod.setObjectId((short) (shapeId % 1024));
-        _note.setShapeId(shapeId % 1024);
+        cod.setObjectId(shapeId);
+        _note.setShapeId(shapeId);
     }
 
     /**
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
index b0f1474..e579277 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
@@ -16,7 +16,7 @@
 ==================================================================== */
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
 import org.apache.poi.ss.usermodel.ConditionalFormatting;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
@@ -73,91 +73,84 @@
  * sheet.addConditionalFormatting(regions, rule);
  * </PRE>
  */
-public final class HSSFConditionalFormatting  implements ConditionalFormatting
-{
-	private final HSSFWorkbook _workbook;
-	private final CFRecordsAggregate cfAggregate;
+public final class HSSFConditionalFormatting  implements ConditionalFormatting {
+    private final HSSFSheet sheet;
+    private final CFRecordsAggregate cfAggregate;
 
-	HSSFConditionalFormatting(HSSFWorkbook workbook, CFRecordsAggregate cfAggregate)
-	{
-		if(workbook == null) {
-			throw new IllegalArgumentException("workbook must not be null");
-		}
-		if(cfAggregate == null) {
-			throw new IllegalArgumentException("cfAggregate must not be null");
-		}
-		_workbook = workbook;
-		this.cfAggregate = cfAggregate;
-	}
-	CFRecordsAggregate getCFRecordsAggregate() {
-		return cfAggregate;
-	}
+    HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate) {
+        if(sheet == null) {
+            throw new IllegalArgumentException("sheet must not be null");
+        }
+        if(cfAggregate == null) {
+            throw new IllegalArgumentException("cfAggregate must not be null");
+        }
+        this.sheet = sheet; 
+        this.cfAggregate = cfAggregate;
+    }
+    CFRecordsAggregate getCFRecordsAggregate() {
+        return cfAggregate;
+    }
 
-	/**
-	 * @deprecated (Aug-2008) use {@link HSSFConditionalFormatting#getFormattingRanges()}
-	 */
-	public org.apache.poi.ss.util.Region[] getFormattingRegions()
-	{
-		CellRangeAddress[] cellRanges = getFormattingRanges();
-		return org.apache.poi.ss.util.Region.convertCellRangesToRegions(cellRanges);
-	}
-	/**
-	 * @return array of <tt>CellRangeAddress</tt>s. never <code>null</code> 
-	 */
-	public CellRangeAddress[] getFormattingRanges() {
-		return cfAggregate.getHeader().getCellRanges();
-	}
+    /**
+     * @deprecated (Aug-2008) use {@link HSSFConditionalFormatting#getFormattingRanges()}
+     */
+    public org.apache.poi.ss.util.Region[] getFormattingRegions() {
+        CellRangeAddress[] cellRanges = getFormattingRanges();
+        return org.apache.poi.ss.util.Region.convertCellRangesToRegions(cellRanges);
+    }
+    /**
+     * @return array of <tt>CellRangeAddress</tt>s. never <code>null</code> 
+     */
+    public CellRangeAddress[] getFormattingRanges() {
+        return cfAggregate.getHeader().getCellRanges();
+    }
 
-	/**
-	 * Replaces an existing Conditional Formatting rule at position idx. 
-	 * Excel allows to create up to 3 Conditional Formatting rules.
-	 * This method can be useful to modify existing  Conditional Formatting rules.
-	 * 
-	 * @param idx position of the rule. Should be between 0 and 2.
-	 * @param cfRule - Conditional Formatting rule
-	 */
-	public void setRule(int idx, HSSFConditionalFormattingRule cfRule)
-	{
-		cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
-	}
+    /**
+     * Replaces an existing Conditional Formatting rule at position idx. 
+     * Older versions of Excel only allow up to 3 Conditional Formatting rules,
+     *  and will ignore rules beyond that, while newer versions are fine.
+     * This method can be useful to modify existing  Conditional Formatting rules.
+     * 
+     * @param idx position of the rule. Should be between 0 and 2 for older Excel versions
+     * @param cfRule - Conditional Formatting rule
+     */
+    public void setRule(int idx, HSSFConditionalFormattingRule cfRule) {
+        cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
+    }
 
     public void setRule(int idx, ConditionalFormattingRule cfRule){
         setRule(idx, (HSSFConditionalFormattingRule)cfRule);
     }
 
-	/**
-	 * add a Conditional Formatting rule. 
-	 * Excel allows to create up to 3 Conditional Formatting rules.
-	 * @param cfRule - Conditional Formatting rule
-	 */
-	public void addRule(HSSFConditionalFormattingRule cfRule)
-	{
-		cfAggregate.addRule(cfRule.getCfRuleRecord());
-	}
+    /**
+     * add a Conditional Formatting rule. 
+     * Excel allows to create up to 3 Conditional Formatting rules.
+     * @param cfRule - Conditional Formatting rule
+     */
+    public void addRule(HSSFConditionalFormattingRule cfRule) {
+        cfAggregate.addRule(cfRule.getCfRuleRecord());
+    }
 
     public void addRule(ConditionalFormattingRule cfRule){
         addRule((HSSFConditionalFormattingRule)cfRule);
     }
 
-	/**
-	 * @return the Conditional Formatting rule at position idx.
-	 */
-	public HSSFConditionalFormattingRule getRule(int idx)
-	{
-		CFRuleRecord ruleRecord = cfAggregate.getRule(idx);
-		return new HSSFConditionalFormattingRule(_workbook, ruleRecord);
-	}
+    /**
+     * @return the Conditional Formatting rule at position idx.
+     */
+    public HSSFConditionalFormattingRule getRule(int idx) {
+        CFRuleBase ruleRecord = cfAggregate.getRule(idx);
+        return new HSSFConditionalFormattingRule(sheet, ruleRecord);
+    }
 
-	/**
-	 * @return number of Conditional Formatting rules.
-	 */
-	public int getNumberOfRules()
-	{
-		return cfAggregate.getNumberOfRules();
-	}
+    /**
+     * @return number of Conditional Formatting rules.
+     */
+    public int getNumberOfRules() {
+        return cfAggregate.getNumberOfRules();
+    }
 
-	public String toString()
-	{
-		return cfAggregate.toString();
-	}
+    public String toString() {
+        return cfAggregate.toString();
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
index 6d88113..a999488 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
@@ -18,12 +18,16 @@
 package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.CFRuleBase;
+import org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator;
 import org.apache.poi.hssf.record.CFRuleRecord;
-import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
 import org.apache.poi.hssf.record.cf.FontFormatting;
+import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
 import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.ConditionType;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
 
 /**
@@ -32,178 +36,224 @@
  * It allows to specify formula based conditions for the Conditional Formatting
  * and the formatting settings such as font, border and pattern.
  */
-public final class HSSFConditionalFormattingRule implements ConditionalFormattingRule
-{
-	private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
+public final class HSSFConditionalFormattingRule implements ConditionalFormattingRule {
+    private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
 
-	private final CFRuleRecord cfRuleRecord;
-	private final HSSFWorkbook workbook;
+    private final CFRuleBase cfRuleRecord;
+    private final HSSFWorkbook workbook;
+    private final HSSFSheet sheet;
 
-	HSSFConditionalFormattingRule(HSSFWorkbook pWorkbook, CFRuleRecord pRuleRecord) {
-		if (pWorkbook == null) {
-			throw new IllegalArgumentException("pWorkbook must not be null");
-		}
-		if (pRuleRecord == null) {
-			throw new IllegalArgumentException("pRuleRecord must not be null");
-		}
-		workbook = pWorkbook;
-		cfRuleRecord = pRuleRecord;
-	}
+    HSSFConditionalFormattingRule(HSSFSheet pSheet, CFRuleBase pRuleRecord) {
+        if (pSheet == null) {
+            throw new IllegalArgumentException("pSheet must not be null");
+        }
+        if (pRuleRecord == null) {
+            throw new IllegalArgumentException("pRuleRecord must not be null");
+        }
+        sheet = pSheet;
+        workbook = pSheet.getWorkbook();
+        cfRuleRecord = pRuleRecord;
+    }
 
-	CFRuleRecord getCfRuleRecord()
-	{
-		return cfRuleRecord;
-	}
+    CFRuleBase getCfRuleRecord()
+    {
+        return cfRuleRecord;
+    }
 
-	private HSSFFontFormatting getFontFormatting(boolean create)
-	{
-		FontFormatting fontFormatting = cfRuleRecord.getFontFormatting();
-		if ( fontFormatting != null)
-		{
-			cfRuleRecord.setFontFormatting(fontFormatting);
-			return new HSSFFontFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			fontFormatting = new FontFormatting();
-			cfRuleRecord.setFontFormatting(fontFormatting);
-			return new HSSFFontFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
+    private HSSFFontFormatting getFontFormatting(boolean create)
+    {
+        FontFormatting fontFormatting = cfRuleRecord.getFontFormatting();
+        if ( fontFormatting != null)
+        {
+            cfRuleRecord.setFontFormatting(fontFormatting);
+            return new HSSFFontFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            fontFormatting = new FontFormatting();
+            cfRuleRecord.setFontFormatting(fontFormatting);
+            return new HSSFFontFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
 
-	/**
-	 * @return - font formatting object  if defined,  <code>null</code> otherwise
-	 */
-	public HSSFFontFormatting getFontFormatting()
-	{
-		return getFontFormatting(false);
-	}
-	/**
-	 * create a new font formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - font formatting object, never returns <code>null</code>.
-	 */
-	public HSSFFontFormatting createFontFormatting()
-	{
-		return getFontFormatting(true);
-	}
+    /**
+     * @return - font formatting object  if defined,  <code>null</code> otherwise
+     */
+    public HSSFFontFormatting getFontFormatting()
+    {
+        return getFontFormatting(false);
+    }
+    /**
+     * create a new font formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - font formatting object, never returns <code>null</code>.
+     */
+    public HSSFFontFormatting createFontFormatting()
+    {
+        return getFontFormatting(true);
+    }
 
-	private HSSFBorderFormatting getBorderFormatting(boolean create)
-	{
-		BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
-		if ( borderFormatting != null)
-		{
-			cfRuleRecord.setBorderFormatting(borderFormatting);
-			return new HSSFBorderFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			borderFormatting = new BorderFormatting();
-			cfRuleRecord.setBorderFormatting(borderFormatting);
-			return new HSSFBorderFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
-	/**
-	 * @return - border formatting object  if defined,  <code>null</code> otherwise
-	 */
-	public HSSFBorderFormatting getBorderFormatting()
-	{
-		return getBorderFormatting(false);
-	}
-	/**
-	 * create a new border formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - border formatting object, never returns <code>null</code>.
-	 */
-	public HSSFBorderFormatting createBorderFormatting()
-	{
-		return getBorderFormatting(true);
-	}
+    private HSSFBorderFormatting getBorderFormatting(boolean create)
+    {
+        BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
+        if ( borderFormatting != null)
+        {
+            cfRuleRecord.setBorderFormatting(borderFormatting);
+            return new HSSFBorderFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            borderFormatting = new BorderFormatting();
+            cfRuleRecord.setBorderFormatting(borderFormatting);
+            return new HSSFBorderFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
+    /**
+     * @return - border formatting object  if defined,  <code>null</code> otherwise
+     */
+    public HSSFBorderFormatting getBorderFormatting()
+    {
+        return getBorderFormatting(false);
+    }
+    /**
+     * create a new border formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - border formatting object, never returns <code>null</code>.
+     */
+    public HSSFBorderFormatting createBorderFormatting()
+    {
+        return getBorderFormatting(true);
+    }
 
-	private HSSFPatternFormatting getPatternFormatting(boolean create)
-	{
-		PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
-		if ( patternFormatting != null)
-		{
-			cfRuleRecord.setPatternFormatting(patternFormatting);
-			return new HSSFPatternFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			patternFormatting = new PatternFormatting();
-			cfRuleRecord.setPatternFormatting(patternFormatting);
-			return new HSSFPatternFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
+    private HSSFPatternFormatting getPatternFormatting(boolean create)
+    {
+        PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
+        if ( patternFormatting != null)
+        {
+            cfRuleRecord.setPatternFormatting(patternFormatting);
+            return new HSSFPatternFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            patternFormatting = new PatternFormatting();
+            cfRuleRecord.setPatternFormatting(patternFormatting);
+            return new HSSFPatternFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
 
-	/**
-	 * @return - pattern formatting object  if defined, <code>null</code> otherwise
-	 */
-	public HSSFPatternFormatting getPatternFormatting()
-	{
-		return getPatternFormatting(false);
-	}
-	/**
-	 * create a new pattern formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - pattern formatting object, never returns <code>null</code>.
-	 */
-	public HSSFPatternFormatting createPatternFormatting()
-	{
-		return getPatternFormatting(true);
-	}
+    /**
+     * @return - pattern formatting object  if defined, <code>null</code> otherwise
+     */
+    public HSSFPatternFormatting getPatternFormatting()
+    {
+        return getPatternFormatting(false);
+    }
+    /**
+     * create a new pattern formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - pattern formatting object, never returns <code>null</code>.
+     */
+    public HSSFPatternFormatting createPatternFormatting()
+    {
+        return getPatternFormatting(true);
+    }
+    
+    private HSSFIconMultiStateFormatting getMultiStateFormatting(boolean create) {
+        if (cfRuleRecord instanceof CFRule12Record) {
+            // Good
+        } else {
+            if (create) throw new IllegalArgumentException("Can't convert a CF into a CF12 record");
+            return null;
+        }
+        CFRule12Record cfRule12Record = (CFRule12Record)cfRuleRecord;
+        IconMultiStateFormatting iconFormatting = cfRule12Record.getMultiStateFormatting();
+        if (iconFormatting != null)
+        {
+            return new HSSFIconMultiStateFormatting(cfRule12Record, sheet);
+        }
+        else if( create )
+        {
+            iconFormatting = cfRule12Record.createMultiStateFormatting();
+            return new HSSFIconMultiStateFormatting(cfRule12Record, sheet);
+        }
+        else
+        {
+            return null;
+        }
+    }
+    
+    /**
+     * @return icon / multi-state formatting object if defined, <code>null</code> otherwise
+     */
+    public HSSFIconMultiStateFormatting getMultiStateFormatting() {
+        return getMultiStateFormatting(false);
+    }
 
-	/**
-	 * @return -  the conditiontype for the cfrule
-	 */
-	public byte getConditionType() {
-		return cfRuleRecord.getConditionType();
-	}
+    /**
+     * create a new icon / multi-state formatting object if it does not exist,
+     * otherwise just return the existing object.
+     */
+    public HSSFIconMultiStateFormatting createMultiStateFormatting() {
+        return getMultiStateFormatting(true);
+    }
+    
+    /**
+     * @return -  the conditiontype for the cfrule
+     */
+    public byte getConditionType() {
+        return cfRuleRecord.getConditionType();
+    }
+    /**
+     * @return -  the conditiontype for the cfrule
+     */
+    public ConditionType getConditionTypeType() {
+        return ConditionType.forId(getConditionType());
+    }
 
-	/**
-	 * @return - the comparisionoperatation for the cfrule
-	 */
-	public byte getComparisonOperation() {
-		return cfRuleRecord.getComparisonOperation();
-	}
+    /**
+     * @return - the comparisionoperatation for the cfrule
+     */
+    public byte getComparisonOperation() {
+        return cfRuleRecord.getComparisonOperation();
+    }
 
-	public String getFormula1()
-	{
-		return toFormulaString(cfRuleRecord.getParsedExpression1());
-	}
+    public String getFormula1()
+    {
+        return toFormulaString(cfRuleRecord.getParsedExpression1());
+    }
 
-	public String getFormula2()
-	{
-		byte conditionType = cfRuleRecord.getConditionType();
-		if (conditionType == CELL_COMPARISON) {
-			byte comparisonOperation = cfRuleRecord.getComparisonOperation();
-			switch(comparisonOperation)
-			{
-				case ComparisonOperator.BETWEEN:
-				case ComparisonOperator.NOT_BETWEEN:
-					return toFormulaString(cfRuleRecord.getParsedExpression2());
-			}
-		}
-		return null;
-	}
+    public String getFormula2() {
+        byte conditionType = cfRuleRecord.getConditionType();
+        if (conditionType == CELL_COMPARISON) {
+            byte comparisonOperation = cfRuleRecord.getComparisonOperation();
+            switch(comparisonOperation) {
+                case ComparisonOperator.BETWEEN:
+                case ComparisonOperator.NOT_BETWEEN:
+                    return toFormulaString(cfRuleRecord.getParsedExpression2());
+            }
+        }
+        return null;
+    }
 
-	private String toFormulaString(Ptg[] parsedExpression)
-	{
-		if(parsedExpression ==null) {
-			return null;
-		}
-		return HSSFFormulaParser.toFormulaString(workbook, parsedExpression);
-	}
+    protected String toFormulaString(Ptg[] parsedExpression) {
+        return toFormulaString(parsedExpression, workbook);
+    }
+    protected static String toFormulaString(Ptg[] parsedExpression, HSSFWorkbook workbook) {
+        if(parsedExpression == null || parsedExpression.length == 0) {
+            return null;
+        }
+        return HSSFFormulaParser.toFormulaString(workbook, parsedExpression);
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingThreshold.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingThreshold.java
new file mode 100644
index 0000000..4ab124c
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingThreshold.java
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import static org.apache.poi.hssf.record.CFRuleBase.parseFormula;
+import static org.apache.poi.hssf.usermodel.HSSFConditionalFormattingRule.toFormulaString;
+
+import org.apache.poi.hssf.record.cf.Threshold;
+
+/**
+ * High level representation for Icon / Multi-State / Databar /
+ *  Colour Scale change thresholds
+ */
+public final class HSSFConditionalFormattingThreshold implements org.apache.poi.ss.usermodel.ConditionalFormattingThreshold {
+    private final Threshold threshold;
+    private final HSSFSheet sheet;
+    private final HSSFWorkbook workbook;
+
+    protected HSSFConditionalFormattingThreshold(Threshold threshold, HSSFSheet sheet) {
+        this.threshold = threshold;
+        this.sheet = sheet;
+        this.workbook = sheet.getWorkbook();
+    }
+    protected Threshold getThreshold() {
+        return threshold;
+    }
+
+    public RangeType getRangeType() {
+        return RangeType.byId(threshold.getType());
+    }
+    public void setRangeType(RangeType type) {
+        threshold.setType((byte)type.id);
+    }
+
+    public String getFormula() {
+        return toFormulaString(threshold.getParsedExpression(), workbook);
+    }
+    public void setFormula(String formula) {
+        threshold.setParsedExpression(parseFormula(formula, sheet));
+    }
+
+    public Double getValue() {
+        return threshold.getValue();
+    }
+    public void setValue(Double value) {
+        threshold.setValue(value);
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java
index 598ea9c..07f5fd4 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java
@@ -17,382 +17,388 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.cf.FontFormatting;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Color;
 /**
  * High level representation for Font Formatting component
  * of Conditional Formatting settings
  */
-public final class HSSFFontFormatting implements org.apache.poi.ss.usermodel.FontFormatting
-{
+public final class HSSFFontFormatting implements org.apache.poi.ss.usermodel.FontFormatting {
+    /** Underline type - None */
+    public final static byte U_NONE              = FontFormatting.U_NONE;
+    /** Underline type - Single */
+    public final static byte U_SINGLE            = FontFormatting.U_SINGLE;
+    /** Underline type - Double */
+    public final static byte U_DOUBLE            = FontFormatting.U_DOUBLE;
+    /**  Underline type - Single Accounting */
+    public final static byte U_SINGLE_ACCOUNTING = FontFormatting.U_SINGLE_ACCOUNTING;
+    /** Underline type - Double Accounting */
+    public final static byte U_DOUBLE_ACCOUNTING = FontFormatting.U_DOUBLE_ACCOUNTING;
 
-	/** Underline type - None */
-	public final static byte U_NONE              = FontFormatting.U_NONE;
-	/** Underline type - Single */
-	public final static byte U_SINGLE            = FontFormatting.U_SINGLE;
-	/** Underline type - Double */
-	public final static byte U_DOUBLE            = FontFormatting.U_DOUBLE;
-	/**  Underline type - Single Accounting */
-	public final static byte U_SINGLE_ACCOUNTING = FontFormatting.U_SINGLE_ACCOUNTING;
-	/** Underline type - Double Accounting */
-	public final static byte U_DOUBLE_ACCOUNTING = FontFormatting.U_DOUBLE_ACCOUNTING;
+    private final FontFormatting fontFormatting;
+    private final HSSFWorkbook workbook;
 
-	private final FontFormatting fontFormatting;
-	
-	protected HSSFFontFormatting(CFRuleRecord cfRuleRecord)
-	{
-		this.fontFormatting = cfRuleRecord.getFontFormatting();
-	}
-	
-	protected FontFormatting getFontFormattingBlock()
-	{
-		return fontFormatting;
-	}
+    protected HSSFFontFormatting(CFRuleBase cfRuleRecord, HSSFWorkbook workbook) {
+        this.fontFormatting = cfRuleRecord.getFontFormatting();
+        this.workbook = workbook;
+    }
 
-	/**
-	 * get the type of super or subscript for the font
-	 *
-	 * @return super or subscript option
-	 * @see #SS_NONE
-	 * @see #SS_SUPER
-	 * @see #SS_SUB
-	 */
-	public short getEscapementType()
-	{
-		return fontFormatting.getEscapementType();
-	}
+    protected FontFormatting getFontFormattingBlock() {
+        return fontFormatting;
+    }
 
-	/**
-	 * @return font color index
-	 */
-	public short getFontColorIndex()
-	{
-		return fontFormatting.getFontColorIndex();
-	}
+    /**
+     * get the type of super or subscript for the font
+     *
+     * @return super or subscript option
+     * @see #SS_NONE
+     * @see #SS_SUPER
+     * @see #SS_SUB
+     */
+    public short getEscapementType()
+    {
+        return fontFormatting.getEscapementType();
+    }
 
-	/**
-	 * gets the height of the font in 1/20th point units
-	 *
-	 * @return fontheight (in points/20); or -1 if not modified
-	 */
-	public int getFontHeight()
-	{
-		return fontFormatting.getFontHeight();
-	}
+    /**
+     * @return font color index
+     */
+    public short getFontColorIndex()
+    {
+        return fontFormatting.getFontColorIndex();
+    }
 
-	/**
-	 * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
-	 * 0x190 for normal and 0x2bc for bold
-	 *
-	 * @return bw - a number between 100-1000 for the fonts "boldness"
-	 */
+    public HSSFColor getFontColor() {
+        return workbook.getCustomPalette().getColor(
+                getFontColorIndex()
+        );
+    }
 
-	public short getFontWeight()
-	{
-		return fontFormatting.getFontWeight();
-	}
+    public void setFontColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            fontFormatting.setFontColorIndex((short)0);
+        } else {
+            fontFormatting.setFontColorIndex(hcolor.getIndex());
+        }
+    }
 
-	/**
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#getRawRecord()
-	 */
-	protected byte[] getRawRecord()
-	{
-		return fontFormatting.getRawRecord();
-	}
+    /**
+     * gets the height of the font in 1/20th point units
+     *
+     * @return fontheight (in points/20); or -1 if not modified
+     */
+    public int getFontHeight() {
+        return fontFormatting.getFontHeight();
+    }
 
-	/**
-	 * get the type of underlining for the font
-	 *
-	 * @return font underlining type
-	 *
-	 * @see #U_NONE
-	 * @see #U_SINGLE
-	 * @see #U_DOUBLE
-	 * @see #U_SINGLE_ACCOUNTING
-	 * @see #U_DOUBLE_ACCOUNTING
-	 */
-	public short getUnderlineType()
-	{
-		return fontFormatting.getUnderlineType();
-	}
+    /**
+     * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
+     * 0x190 for normal and 0x2bc for bold
+     *
+     * @return bw - a number between 100-1000 for the fonts "boldness"
+     */
+    public short getFontWeight() {
+        return fontFormatting.getFontWeight();
+    }
 
-	/**
-	 * get whether the font weight is set to bold or not
-	 *
-	 * @return bold - whether the font is bold or not
-	 */
-	public boolean isBold()
-	{
-		return fontFormatting.isFontWeightModified() && fontFormatting.isBold();
-	}
+    /**
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#getRawRecord()
+     */
+    protected byte[] getRawRecord() {
+        return fontFormatting.getRawRecord();
+    }
 
-	/**
-	 * @return true if escapement type was modified from default   
-	 */
-	public boolean isEscapementTypeModified()
-	{
-		return fontFormatting.isEscapementTypeModified();
-	}
+    /**
+     * get the type of underlining for the font
+     *
+     * @return font underlining type
+     *
+     * @see #U_NONE
+     * @see #U_SINGLE
+     * @see #U_DOUBLE
+     * @see #U_SINGLE_ACCOUNTING
+     * @see #U_DOUBLE_ACCOUNTING
+     */
+    public short getUnderlineType()
+    {
+        return fontFormatting.getUnderlineType();
+    }
 
-	/**
-	 * @return true if font cancellation was modified from default   
-	 */
-	public boolean isFontCancellationModified()
-	{
-		return fontFormatting.isFontCancellationModified();
-	}
+    /**
+     * get whether the font weight is set to bold or not
+     *
+     * @return bold - whether the font is bold or not
+     */
+    public boolean isBold()
+    {
+        return fontFormatting.isFontWeightModified() && fontFormatting.isBold();
+    }
 
-	/**
-	 * @return true if font outline type was modified from default   
-	 */
-	public boolean isFontOutlineModified()
-	{
-		return fontFormatting.isFontOutlineModified();
-	}
+    /**
+     * @return true if escapement type was modified from default   
+     */
+    public boolean isEscapementTypeModified()
+    {
+        return fontFormatting.isEscapementTypeModified();
+    }
 
-	/**
-	 * @return true if font shadow type was modified from default   
-	 */
-	public boolean isFontShadowModified()
-	{
-		return fontFormatting.isFontShadowModified();
-	}
+    /**
+     * @return true if font cancellation was modified from default   
+     */
+    public boolean isFontCancellationModified()
+    {
+        return fontFormatting.isFontCancellationModified();
+    }
 
-	/**
-	 * @return true if font style was modified from default   
-	 */
-	public boolean isFontStyleModified()
-	{
-		return fontFormatting.isFontStyleModified();
-	}
+    /**
+     * @return true if font outline type was modified from default   
+     */
+    public boolean isFontOutlineModified()
+    {
+        return fontFormatting.isFontOutlineModified();
+    }
 
-	/**
-	 * @return true if font style was set to <i>italic</i> 
-	 */
-	public boolean isItalic()
-	{
-		return fontFormatting.isFontStyleModified() && fontFormatting.isItalic();
-	}
+    /**
+     * @return true if font shadow type was modified from default   
+     */
+    public boolean isFontShadowModified()
+    {
+        return fontFormatting.isFontShadowModified();
+    }
 
-	/**
-	 * @return true if font outline is on
-	 */
-	public boolean isOutlineOn()
-	{
-		return fontFormatting.isFontOutlineModified() && fontFormatting.isOutlineOn();
-	}
+    /**
+     * @return true if font style was modified from default   
+     */
+    public boolean isFontStyleModified()
+    {
+        return fontFormatting.isFontStyleModified();
+    }
 
-	/**
-	 * @return true if font shadow is on
-	 */
-	public boolean isShadowOn()
-	{
-		return fontFormatting.isFontOutlineModified() && fontFormatting.isShadowOn();
-	}
+    /**
+     * @return true if font style was set to <i>italic</i> 
+     */
+    public boolean isItalic()
+    {
+        return fontFormatting.isFontStyleModified() && fontFormatting.isItalic();
+    }
 
-	/**
-	 * @return true if font strikeout is on
-	 */
-	public boolean isStruckout()
-	{
-		return fontFormatting.isFontCancellationModified() && fontFormatting.isStruckout();
-	}
+    /**
+     * @return true if font outline is on
+     */
+    public boolean isOutlineOn()
+    {
+        return fontFormatting.isFontOutlineModified() && fontFormatting.isOutlineOn();
+    }
 
-	/**
-	 * @return true if font underline type was modified from default   
-	 */
-	public boolean isUnderlineTypeModified()
-	{
-		return fontFormatting.isUnderlineTypeModified();
-	}
+    /**
+     * @return true if font shadow is on
+     */
+    public boolean isShadowOn()
+    {
+        return fontFormatting.isFontOutlineModified() && fontFormatting.isShadowOn();
+    }
 
-	/**
-	 * @return true if font weight was modified from default   
-	 */
-	public boolean isFontWeightModified()
-	{
-		return fontFormatting.isFontWeightModified();
-	}
+    /**
+     * @return true if font strikeout is on
+     */
+    public boolean isStruckout()
+    {
+        return fontFormatting.isFontCancellationModified() && fontFormatting.isStruckout();
+    }
 
-	/**
-	 * set font style options.
-	 * 
-	 * @param italic - if true, set posture style to italic, otherwise to normal 
-	 * @param bold if true, set font weight to bold, otherwise to normal
-	 */
-	
-	public void setFontStyle(boolean italic, boolean bold)
-	{
-		boolean modified = italic || bold;
-		fontFormatting.setItalic(italic);
-		fontFormatting.setBold(bold);
-		fontFormatting.setFontStyleModified(modified);
-		fontFormatting.setFontWieghtModified(modified);
-	}
+    /**
+     * @return true if font underline type was modified from default   
+     */
+    public boolean isUnderlineTypeModified()
+    {
+        return fontFormatting.isUnderlineTypeModified();
+    }
 
-	/**
-	 * set font style options to default values (non-italic, non-bold)
-	 */
-	public void resetFontStyle()
-	{
-		setFontStyle(false,false);
-	}
+    /**
+     * @return true if font weight was modified from default   
+     */
+    public boolean isFontWeightModified()
+    {
+        return fontFormatting.isFontWeightModified();
+    }
 
-	/**
-	 * set the escapement type for the font
-	 *
-	 * @param escapementType  super or subscript option
-	 * @see #SS_NONE
-	 * @see #SS_SUPER
-	 * @see #SS_SUB
-	 */
-	public void setEscapementType(short escapementType)
-	{
-		switch(escapementType)
-		{
-			case HSSFFontFormatting.SS_SUB:
-			case HSSFFontFormatting.SS_SUPER:
-				fontFormatting.setEscapementType(escapementType);
-				fontFormatting.setEscapementTypeModified(true);
-				break;
-			case HSSFFontFormatting.SS_NONE:
-				fontFormatting.setEscapementType(escapementType);
-				fontFormatting.setEscapementTypeModified(false);
-				break;
-			default:
-		}
-	}
+    /**
+     * set font style options.
+     * 
+     * @param italic - if true, set posture style to italic, otherwise to normal 
+     * @param bold if true, set font weight to bold, otherwise to normal
+     */
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setEscapementTypeModified(boolean)
-	 */
-	public void setEscapementTypeModified(boolean modified)
-	{
-		fontFormatting.setEscapementTypeModified(modified);
-	}
+    public void setFontStyle(boolean italic, boolean bold)
+    {
+        boolean modified = italic || bold;
+        fontFormatting.setItalic(italic);
+        fontFormatting.setBold(bold);
+        fontFormatting.setFontStyleModified(modified);
+        fontFormatting.setFontWieghtModified(modified);
+    }
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontCancellationModified(boolean)
-	 */
-	public void setFontCancellationModified(boolean modified)
-	{
-		fontFormatting.setFontCancellationModified(modified);
-	}
+    /**
+     * set font style options to default values (non-italic, non-bold)
+     */
+    public void resetFontStyle()
+    {
+        setFontStyle(false,false);
+    }
 
-	/**
-	 * @param fci
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontColorIndex(short)
-	 */
-	public void setFontColorIndex(short fci)
-	{
-		fontFormatting.setFontColorIndex(fci);
-	}
+    /**
+     * set the escapement type for the font
+     *
+     * @param escapementType  super or subscript option
+     * @see #SS_NONE
+     * @see #SS_SUPER
+     * @see #SS_SUB
+     */
+    public void setEscapementType(short escapementType) {
+        switch(escapementType) {
+            case HSSFFontFormatting.SS_SUB:
+            case HSSFFontFormatting.SS_SUPER:
+                fontFormatting.setEscapementType(escapementType);
+                fontFormatting.setEscapementTypeModified(true);
+                break;
+            case HSSFFontFormatting.SS_NONE:
+                fontFormatting.setEscapementType(escapementType);
+                fontFormatting.setEscapementTypeModified(false);
+                break;
+            default:
+        }
+    }
 
-	/**
-	 * @param height
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontHeight(int)
-	 */
-	public void setFontHeight(int height)
-	{
-		fontFormatting.setFontHeight(height);
-	}
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setEscapementTypeModified(boolean)
+     */
+    public void setEscapementTypeModified(boolean modified) {
+        fontFormatting.setEscapementTypeModified(modified);
+    }
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontOutlineModified(boolean)
-	 */
-	public void setFontOutlineModified(boolean modified)
-	{
-		fontFormatting.setFontOutlineModified(modified);
-	}
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontCancellationModified(boolean)
+     */
+    public void setFontCancellationModified(boolean modified)
+    {
+        fontFormatting.setFontCancellationModified(modified);
+    }
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontShadowModified(boolean)
-	 */
-	public void setFontShadowModified(boolean modified)
-	{
-		fontFormatting.setFontShadowModified(modified);
-	}
+    /**
+     * @param fci
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontColorIndex(short)
+     */
+    public void setFontColorIndex(short fci)
+    {
+        fontFormatting.setFontColorIndex(fci);
+    }
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontStyleModified(boolean)
-	 */
-	public void setFontStyleModified(boolean modified)
-	{
-		fontFormatting.setFontStyleModified(modified);
-	}
+    /**
+     * @param height
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontHeight(int)
+     */
+    public void setFontHeight(int height)
+    {
+        fontFormatting.setFontHeight(height);
+    }
 
-	/**
-	 * @param on
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setOutline(boolean)
-	 */
-	public void setOutline(boolean on)
-	{
-		fontFormatting.setOutline(on);
-		fontFormatting.setFontOutlineModified(on);
-	}
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontOutlineModified(boolean)
+     */
+    public void setFontOutlineModified(boolean modified)
+    {
+        fontFormatting.setFontOutlineModified(modified);
+    }
 
-	/**
-	 * @param on
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setShadow(boolean)
-	 */
-	public void setShadow(boolean on)
-	{
-		fontFormatting.setShadow(on);
-		fontFormatting.setFontShadowModified(on);
-	}
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontShadowModified(boolean)
+     */
+    public void setFontShadowModified(boolean modified)
+    {
+        fontFormatting.setFontShadowModified(modified);
+    }
 
-	/**
-	 * @param strike
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setStrikeout(boolean)
-	 */
-	public void setStrikeout(boolean strike)
-	{
-		fontFormatting.setStrikeout(strike);
-		fontFormatting.setFontCancellationModified(strike);
-	}
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontStyleModified(boolean)
+     */
+    public void setFontStyleModified(boolean modified)
+    {
+        fontFormatting.setFontStyleModified(modified);
+    }
 
-	/**
-	 * set the type of underlining type for the font
-	 *
-	 * @param underlineType  super or subscript option
-	 *
-	 * @see #U_NONE
-	 * @see #U_SINGLE
-	 * @see #U_DOUBLE
-	 * @see #U_SINGLE_ACCOUNTING
-	 * @see #U_DOUBLE_ACCOUNTING
-	 */
-	public void setUnderlineType(short underlineType)
-	{
-		switch(underlineType)
-		{
-			case HSSFFontFormatting.U_SINGLE:
-			case HSSFFontFormatting.U_DOUBLE:
-			case HSSFFontFormatting.U_SINGLE_ACCOUNTING:
-			case HSSFFontFormatting.U_DOUBLE_ACCOUNTING:
-				fontFormatting.setUnderlineType(underlineType);
-				setUnderlineTypeModified(true);
-				break;
-				
-			case HSSFFontFormatting.U_NONE:
-				fontFormatting.setUnderlineType(underlineType);
-				setUnderlineTypeModified(false);
-				break;
-			default:
-		}
-	}
+    /**
+     * @param on
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setOutline(boolean)
+     */
+    public void setOutline(boolean on)
+    {
+        fontFormatting.setOutline(on);
+        fontFormatting.setFontOutlineModified(on);
+    }
 
-	/**
-	 * @param modified
-	 * @see org.apache.poi.hssf.record.cf.FontFormatting#setUnderlineTypeModified(boolean)
-	 */
-	public void setUnderlineTypeModified(boolean modified)
-	{
-		fontFormatting.setUnderlineTypeModified(modified);
-	}
+    /**
+     * @param on
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setShadow(boolean)
+     */
+    public void setShadow(boolean on)
+    {
+        fontFormatting.setShadow(on);
+        fontFormatting.setFontShadowModified(on);
+    }
+
+    /**
+     * @param strike
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setStrikeout(boolean)
+     */
+    public void setStrikeout(boolean strike)
+    {
+        fontFormatting.setStrikeout(strike);
+        fontFormatting.setFontCancellationModified(strike);
+    }
+
+    /**
+     * set the type of underlining type for the font
+     *
+     * @param underlineType  super or subscript option
+     *
+     * @see #U_NONE
+     * @see #U_SINGLE
+     * @see #U_DOUBLE
+     * @see #U_SINGLE_ACCOUNTING
+     * @see #U_DOUBLE_ACCOUNTING
+     */
+    public void setUnderlineType(short underlineType) {
+        switch(underlineType) {
+            case HSSFFontFormatting.U_SINGLE:
+            case HSSFFontFormatting.U_DOUBLE:
+            case HSSFFontFormatting.U_SINGLE_ACCOUNTING:
+            case HSSFFontFormatting.U_DOUBLE_ACCOUNTING:
+                fontFormatting.setUnderlineType(underlineType);
+                setUnderlineTypeModified(true);
+                break;
+    
+            case HSSFFontFormatting.U_NONE:
+                fontFormatting.setUnderlineType(underlineType);
+                setUnderlineTypeModified(false);
+                break;
+            default:
+        }
+    }
+
+    /**
+     * @param modified
+     * @see org.apache.poi.hssf.record.cf.FontFormatting#setUnderlineTypeModified(boolean)
+     */
+    public void setUnderlineTypeModified(boolean modified)
+    {
+        fontFormatting.setUnderlineTypeModified(modified);
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFIconMultiStateFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFIconMultiStateFormatting.java
new file mode 100644
index 0000000..e93d5c9
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFIconMultiStateFormatting.java
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
+import org.apache.poi.hssf.record.cf.Threshold;
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
+
+/**
+ * High level representation for Icon / Multi-State Formatting 
+ *  component of Conditional Formatting settings
+ */
+public final class HSSFIconMultiStateFormatting implements org.apache.poi.ss.usermodel.IconMultiStateFormatting {
+    private final HSSFSheet sheet;
+    private final CFRule12Record cfRule12Record;
+    private final IconMultiStateFormatting iconFormatting;
+
+    protected HSSFIconMultiStateFormatting(CFRule12Record cfRule12Record, HSSFSheet sheet) {
+        this.sheet = sheet;
+        this.cfRule12Record = cfRule12Record;
+        this.iconFormatting = this.cfRule12Record.getMultiStateFormatting();
+    }
+
+    public IconSet getIconSet() {
+        return iconFormatting.getIconSet();
+    }
+    public void setIconSet(IconSet set) {
+        iconFormatting.setIconSet(set);
+    }
+
+    public boolean isIconOnly() {
+        return iconFormatting.isIconOnly();
+    }
+    public void setIconOnly(boolean only) {
+        iconFormatting.setIconOnly(only);
+    }
+
+    public boolean isReversed() {
+        return iconFormatting.isReversed();
+    }
+    public void setReversed(boolean reversed) {
+        iconFormatting.setReversed(reversed);
+    }
+
+    public HSSFConditionalFormattingThreshold[] getThresholds() {
+        Threshold[] t = iconFormatting.getThresholds();
+        HSSFConditionalFormattingThreshold[] ht = new HSSFConditionalFormattingThreshold[t.length];
+        for (int i=0; i<t.length; i++) {
+            ht[i] = new HSSFConditionalFormattingThreshold(t[i], sheet);
+        }
+        return ht;
+    }
+
+    public void setThresholds(ConditionalFormattingThreshold[] thresholds) {
+        Threshold[] t = new Threshold[thresholds.length];
+        for (int i=0; i<t.length; i++) {
+            t[i] = ((HSSFConditionalFormattingThreshold)thresholds[i]).getThreshold();
+        }
+        iconFormatting.setThresholds(t);
+    }
+
+    public HSSFConditionalFormattingThreshold createThreshold() {
+        return new HSSFConditionalFormattingThreshold(new Threshold(), sheet);
+    }
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
index 2c162b9..667c83c 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
@@ -45,7 +45,6 @@
 import org.apache.poi.hssf.util.CellReference;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.usermodel.Chart;
 import org.apache.poi.ss.usermodel.ClientAnchor;
 import org.apache.poi.ss.usermodel.Drawing;
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java
index 0430342..1f521c5 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java
@@ -17,88 +17,116 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Color;
 
 /**
  * High level representation for Conditional Formatting settings
  */
-public class HSSFPatternFormatting implements org.apache.poi.ss.usermodel.PatternFormatting
-{
-	private final CFRuleRecord cfRuleRecord;
-	private final PatternFormatting patternFormatting;
-	
-	protected HSSFPatternFormatting(CFRuleRecord cfRuleRecord)
-	{
-		this.cfRuleRecord = cfRuleRecord; 
-		this.patternFormatting = cfRuleRecord.getPatternFormatting();
-	}
+public class HSSFPatternFormatting implements org.apache.poi.ss.usermodel.PatternFormatting {
+    private final HSSFWorkbook workbook;
+    private final CFRuleBase cfRuleRecord;
+    private final PatternFormatting patternFormatting;
 
-	protected PatternFormatting getPatternFormattingBlock()
-	{
-		return patternFormatting;
-	}
+    protected HSSFPatternFormatting(CFRuleBase cfRuleRecord, HSSFWorkbook workbook) {
+        this.workbook = workbook;
+        this.cfRuleRecord = cfRuleRecord; 
+        this.patternFormatting = cfRuleRecord.getPatternFormatting();
+    }
 
-	/**
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillBackgroundColor()
-	 */
-	public short getFillBackgroundColor()
-	{
-		return (short)patternFormatting.getFillBackgroundColor();
-	}
+    protected PatternFormatting getPatternFormattingBlock()
+    {
+        return patternFormatting;
+    }
 
-	/**
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillForegroundColor()
-	 */
-	public short getFillForegroundColor()
-	{
-		return (short)patternFormatting.getFillForegroundColor();
-	}
+    public HSSFColor getFillBackgroundColorColor() {
+        return workbook.getCustomPalette().getColor(getFillBackgroundColor());
+    }
 
-	/**
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillPattern()
-	 */
-	public short getFillPattern()
-	{
-		return (short)patternFormatting.getFillPattern();
-	}
+    public HSSFColor getFillForegroundColorColor() {
+        return workbook.getCustomPalette().getColor(getFillForegroundColor());
+    }
 
-	/**
-	 * @param bg
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillBackgroundColor(int)
-	 */
-	public void setFillBackgroundColor(short bg)
-	{
-		patternFormatting.setFillBackgroundColor(bg);
-		if( bg != 0)
-		{
-			cfRuleRecord.setPatternBackgroundColorModified(true);
-		}
-	}
+    /**
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillBackgroundColor()
+     */
+    public short getFillBackgroundColor()
+    {
+        return (short)patternFormatting.getFillBackgroundColor();
+    }
 
-	/**
-	 * @param fg
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillForegroundColor(int)
-	 */
-	public void setFillForegroundColor(short fg)
-	{
-		patternFormatting.setFillForegroundColor(fg);
-		if( fg != 0)
-		{
-			cfRuleRecord.setPatternColorModified(true);
-		}
-	}
+    /**
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillForegroundColor()
+     */
+    public short getFillForegroundColor()
+    {
+        return (short)patternFormatting.getFillForegroundColor();
+    }
 
-	/**
-	 * @param fp
-	 * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillPattern(int)
-	 */
-	public void setFillPattern(short fp)
-	{
-		patternFormatting.setFillPattern(fp);
-		if( fp != 0)
-		{
-			cfRuleRecord.setPatternStyleModified(true);
-		}
-	}
+    /**
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#getFillPattern()
+     */
+    public short getFillPattern()
+    {
+        return (short)patternFormatting.getFillPattern();
+    }
+
+    public void setFillBackgroundColor(Color bg) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(bg);
+        if (hcolor == null) {
+            setFillBackgroundColor((short)0);
+        } else {
+            setFillBackgroundColor(hcolor.getIndex());
+        }
+    }
+
+    public void setFillForegroundColor(Color fg) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(fg);
+        if (hcolor == null) {
+            setFillForegroundColor((short)0);
+        } else {
+            setFillForegroundColor(hcolor.getIndex());
+        }
+    }
+
+    /**
+     * @param bg
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillBackgroundColor(int)
+     */
+    public void setFillBackgroundColor(short bg)
+    {
+        patternFormatting.setFillBackgroundColor(bg);
+        if( bg != 0)
+        {
+            cfRuleRecord.setPatternBackgroundColorModified(true);
+        }
+    }
+
+    /**
+     * @param fg
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillForegroundColor(int)
+     */
+    public void setFillForegroundColor(short fg)
+    {
+        patternFormatting.setFillForegroundColor(fg);
+        if( fg != 0)
+        {
+            cfRuleRecord.setPatternColorModified(true);
+        }
+    }
+
+    /**
+     * @param fp
+     * @see org.apache.poi.hssf.record.cf.PatternFormatting#setFillPattern(int)
+     */
+    public void setFillPattern(short fp)
+    {
+        patternFormatting.setFillPattern(fp);
+        if( fp != 0)
+        {
+            cfRuleRecord.setPatternStyleModified(true);
+        }
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
index 3e82fbe..ef1b13b 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
@@ -29,13 +29,6 @@
  * Factory class for producing Excel Shapes from Escher records

  */

 public class HSSFShapeFactory {

-

-    private final static short       OBJECT_TYPE_LINE               = 1;

-    private final static short       OBJECT_TYPE_RECTANGLE          = 2;

-    private final static short       OBJECT_TYPE_OVAL               = 3;

-    private final static short       OBJECT_TYPE_ARC                = 4;

-    private final static short       OBJECT_TYPE_PICTURE            = 8;

-

     /**

      * build shape tree from escher container

      * @param container root escher container from which escher records must be taken

@@ -81,7 +74,7 @@
                 return;

             }

             CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);

-            HSSFShape shape;

+            final HSSFShape shape;

             switch (cmo.getObjectType()) {

                 case CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE:

                     shape = new HSSFPicture(container, objRecord);

@@ -97,11 +90,15 @@
                     break;

                 case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING:

                     EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);

-                    EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);

-                    if (null != property) {

-                        shape = new HSSFPolygon(container, objRecord, txtRecord);

+                    if(optRecord == null) {

+                    	shape = new HSSFSimpleShape(container, objRecord, txtRecord);

                     } else {

-                        shape = new HSSFSimpleShape(container, objRecord, txtRecord);

+                        EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);

+                        if (null != property) {

+                            shape = new HSSFPolygon(container, objRecord, txtRecord);

+                        } else {

+                            shape = new HSSFSimpleShape(container, objRecord, txtRecord);

+                        }

                     }

                     break;

                 case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT:

diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index 8458152..268a680 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -868,6 +868,17 @@
     }
 
     /**
+     * @return the list of merged regions
+     */
+    public List<CellRangeAddress> getMergedRegions() {
+        List<CellRangeAddress> addresses = new ArrayList<CellRangeAddress>();
+        for (int i=0; i < _sheet.getNumMergedRegions(); i++) {
+            addresses.add(_sheet.getMergedRegionAt(i));
+        }
+        return addresses;
+    }
+
+    /**
      * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
      *         be the third row if say for instance the second row is undefined.
      *         Call getRowNum() on each row if you care which one it is.
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
index ce6bf76..deca836 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
@@ -17,142 +17,156 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.usermodel.ConditionalFormatting;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.SpreadsheetVersion;
 
 /**
  * The 'Conditional Formatting' facet of <tt>HSSFSheet</tt>
  */
 public final class HSSFSheetConditionalFormatting implements SheetConditionalFormatting {
+    private final HSSFSheet _sheet;
+    private final ConditionalFormattingTable _conditionalFormattingTable;
 
-	private final HSSFSheet _sheet;
-	private final ConditionalFormattingTable _conditionalFormattingTable;
+    /* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) {
+        _sheet = sheet;
+        _conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable();
+    }
 
-	/* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) {
-		_sheet = sheet;
-		_conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable();
-	}
-
-	/**
-	 * A factory method allowing to create a conditional formatting rule
-	 * with a cell comparison operator<p/>
-	 * TODO - formulas containing cell references are currently not parsed properly
-	 *
-	 * @param comparisonOperation - a constant value from
-	 *		 <tt>{@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}</tt>: <p>
-	 * <ul>
-	 *		 <li>BETWEEN</li>
-	 *		 <li>NOT_BETWEEN</li>
-	 *		 <li>EQUAL</li>
-	 *		 <li>NOT_EQUAL</li>
-	 *		 <li>GT</li>
-	 *		 <li>LT</li>
-	 *		 <li>GE</li>
-	 *		 <li>LE</li>
-	 * </ul>
-	 * </p>
-	 * @param formula1 - formula for the valued, compared with the cell
-	 * @param formula2 - second formula (only used with
-	 * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and
-	 * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations)
-	 */
-	public HSSFConditionalFormattingRule createConditionalFormattingRule(
-			byte comparisonOperation,
-			String formula1,
-			String formula2) {
-
-		HSSFWorkbook wb = _sheet.getWorkbook();
-		CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2);
-		return new HSSFConditionalFormattingRule(wb, rr);
-	}
+    /**
+     * A factory method allowing to create a conditional formatting rule
+     * with a cell comparison operator<p/>
+     * TODO - formulas containing cell references are currently not parsed properly
+     *
+     * @param comparisonOperation - a constant value from
+     *		 <tt>{@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}</tt>: <p>
+     * <ul>
+     *		 <li>BETWEEN</li>
+     *		 <li>NOT_BETWEEN</li>
+     *		 <li>EQUAL</li>
+     *		 <li>NOT_EQUAL</li>
+     *		 <li>GT</li>
+     *		 <li>LT</li>
+     *		 <li>GE</li>
+     *		 <li>LE</li>
+     * </ul>
+     * </p>
+     * @param formula1 - formula for the valued, compared with the cell
+     * @param formula2 - second formula (only used with
+     * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and
+     * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations)
+     */
+    public HSSFConditionalFormattingRule createConditionalFormattingRule(
+            byte comparisonOperation,
+            String formula1,
+            String formula2) {
+        CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2);
+        return new HSSFConditionalFormattingRule(_sheet, rr);
+    }
 
     public HSSFConditionalFormattingRule createConditionalFormattingRule(
             byte comparisonOperation,
             String formula1) {
-
-        HSSFWorkbook wb = _sheet.getWorkbook();
         CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, null);
-        return new HSSFConditionalFormattingRule(wb, rr);
+        return new HSSFConditionalFormattingRule(_sheet, rr);
     }
 
-	/**
-	 * A factory method allowing to create a conditional formatting rule with a formula.<br>
-	 *
-	 * The formatting rules are applied by Excel when the value of the formula not equal to 0.<p/>
-	 * TODO - formulas containing cell references are currently not parsed properly
-	 * @param formula - formula for the valued, compared with the cell
-	 */
-	public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
-		HSSFWorkbook wb = _sheet.getWorkbook();
-		CFRuleRecord rr = CFRuleRecord.create(_sheet, formula);
-		return new HSSFConditionalFormattingRule(wb, rr);
-	}
+    /**
+     * A factory method allowing to create a conditional formatting rule with a formula.<br>
+     *
+     * The formatting rules are applied by Excel when the value of the formula not equal to 0.<p/>
+     * TODO - formulas containing cell references are currently not parsed properly
+     * @param formula - formula for the valued, compared with the cell
+     */
+    public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
+        CFRuleRecord rr = CFRuleRecord.create(_sheet, formula);
+        return new HSSFConditionalFormattingRule(_sheet, rr);
+    }
 
-	/**
-	 * Adds a copy of HSSFConditionalFormatting object to the sheet
-	 * <p>This method could be used to copy HSSFConditionalFormatting object
-	 * from one sheet to another. For example:
-	 * <pre>
-	 * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
-	 * newSheet.addConditionalFormatting(cf);
-	 * </pre>
-	 *
-	 * @param cf HSSFConditionalFormatting object
-	 * @return index of the new Conditional Formatting object
-	 */
-	public int addConditionalFormatting( HSSFConditionalFormatting cf ) {
-		CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate();
+    /**
+     * A factory method allowing the creation of conditional formatting
+     *  rules using an Icon Set / Multi-State formatting.
+     * The thresholds for it will be created, but will be empty
+     *  and require configuring with 
+     *  {@link HSSFConditionalFormattingRule#getMultiStateFormatting()}
+     *  then
+     *  {@link HSSFIconMultiStateFormatting#getThresholds()}
+     */
+    public HSSFConditionalFormattingRule createConditionalFormattingRule(
+            IconSet iconSet) {
+        CFRule12Record rr = CFRule12Record.create(_sheet, iconSet);
+        return new HSSFConditionalFormattingRule(_sheet, rr);
+    }
 
-		return _conditionalFormattingTable.add(cfraClone);
-	}
+    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs
+
+    /**
+     * Adds a copy of HSSFConditionalFormatting object to the sheet
+     * <p>This method could be used to copy HSSFConditionalFormatting object
+     * from one sheet to another. For example:
+     * <pre>
+     * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
+     * newSheet.addConditionalFormatting(cf);
+     * </pre>
+     *
+     * @param cf HSSFConditionalFormatting object
+     * @return index of the new Conditional Formatting object
+     */
+    public int addConditionalFormatting( HSSFConditionalFormatting cf ) {
+        CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate();
+
+        return _conditionalFormattingTable.add(cfraClone);
+    }
 
     public int addConditionalFormatting( ConditionalFormatting cf ) {
         return addConditionalFormatting((HSSFConditionalFormatting)cf);
     }
 
-	/**
-	 * @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
-	 */
-	public int addConditionalFormatting(org.apache.poi.ss.util.Region[] regions, HSSFConditionalFormattingRule[] cfRules) {
-		return addConditionalFormatting(org.apache.poi.ss.util.Region.convertRegionsToCellRanges(regions), cfRules);
-	}
-	/**
-	 * Allows to add a new Conditional Formatting set to the sheet.
-	 *
-	 * @param regions - list of rectangular regions to apply conditional formatting rules
-	 * @param cfRules - set of up to three conditional formatting rules
-	 *
-	 * @return index of the newly created Conditional Formatting object
-	 */
-	public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) {
-		if (regions == null) {
-			throw new IllegalArgumentException("regions must not be null");
-		}
-		for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97);
+    /**
+     * @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
+     */
+    public int addConditionalFormatting(org.apache.poi.ss.util.Region[] regions, HSSFConditionalFormattingRule[] cfRules) {
+        return addConditionalFormatting(org.apache.poi.ss.util.Region.convertRegionsToCellRanges(regions), cfRules);
+    }
+    /**
+     * Allows to add a new Conditional Formatting set to the sheet.
+     *
+     * @param regions - list of rectangular regions to apply conditional formatting rules
+     * @param cfRules - set of up to three conditional formatting rules
+     *
+     * @return index of the newly created Conditional Formatting object
+     */
+    public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) {
+        if (regions == null) {
+            throw new IllegalArgumentException("regions must not be null");
+        }
+        for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97);
 
-		if (cfRules == null) {
-			throw new IllegalArgumentException("cfRules must not be null");
-		}
-		if (cfRules.length == 0) {
-			throw new IllegalArgumentException("cfRules must not be empty");
-		}
-		if (cfRules.length > 3) {
-			throw new IllegalArgumentException("Number of rules must not exceed 3");
-		}
+        if (cfRules == null) {
+            throw new IllegalArgumentException("cfRules must not be null");
+        }
+        if (cfRules.length == 0) {
+            throw new IllegalArgumentException("cfRules must not be empty");
+        }
+        if (cfRules.length > 3) {
+            throw new IllegalArgumentException("Number of rules must not exceed 3");
+        }
 
-		CFRuleRecord[] rules = new CFRuleRecord[cfRules.length];
-		for (int i = 0; i != cfRules.length; i++) {
-			rules[i] = cfRules[i].getCfRuleRecord();
-		}
-		CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules);
-		return _conditionalFormattingTable.add(cfra);
-	}
+        CFRuleBase[] rules = new CFRuleBase[cfRules.length];
+        for (int i = 0; i != cfRules.length; i++) {
+            rules[i] = cfRules[i].getCfRuleRecord();
+        }
+        CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules);
+        return _conditionalFormattingTable.add(cfra);
+    }
 
     public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {
         HSSFConditionalFormattingRule[] hfRules;
@@ -164,70 +178,61 @@
         return addConditionalFormatting(regions, hfRules);
     }
 
-	public int addConditionalFormatting(CellRangeAddress[] regions,
-			HSSFConditionalFormattingRule rule1)
-	{
-		return addConditionalFormatting(regions,
-				rule1 == null ? null : new HSSFConditionalFormattingRule[]
-				{
-					rule1
-				});
-	}
+    public int addConditionalFormatting(CellRangeAddress[] regions,
+            HSSFConditionalFormattingRule rule1) {
+        return addConditionalFormatting(regions, rule1 == null ? 
+                    null : new HSSFConditionalFormattingRule[] { rule1 }
+        );
+    }
 
     public int addConditionalFormatting(CellRangeAddress[] regions,
-            ConditionalFormattingRule rule1)
-    {
+            ConditionalFormattingRule rule1) {
         return addConditionalFormatting(regions,  (HSSFConditionalFormattingRule)rule1);
     }
 
-	public int addConditionalFormatting(CellRangeAddress[] regions,
-			HSSFConditionalFormattingRule rule1,
-			HSSFConditionalFormattingRule rule2)
-	{
-		return addConditionalFormatting(regions,
-				new HSSFConditionalFormattingRule[]
-				{
-						rule1, rule2
-				});
-	}
+    public int addConditionalFormatting(CellRangeAddress[] regions,
+            HSSFConditionalFormattingRule rule1,
+            HSSFConditionalFormattingRule rule2) {
+        return addConditionalFormatting(regions,
+                new HSSFConditionalFormattingRule[] { rule1, rule2 });
+    }
 
     public int addConditionalFormatting(CellRangeAddress[] regions,
             ConditionalFormattingRule rule1,
-            ConditionalFormattingRule rule2)
-    {
+            ConditionalFormattingRule rule2) {
         return addConditionalFormatting(regions,
                 (HSSFConditionalFormattingRule)rule1,
                 (HSSFConditionalFormattingRule)rule2
-                );
+        );
     }
 
-	/**
-	* gets Conditional Formatting object at a particular index
-	*
-	* @param index
-	*			of the Conditional Formatting object to fetch
-	* @return Conditional Formatting object
-	*/
-	public HSSFConditionalFormatting getConditionalFormattingAt(int index) {
-		CFRecordsAggregate cf = _conditionalFormattingTable.get(index);
-		if (cf == null) {
-			return null;
-		}
-		return new HSSFConditionalFormatting(_sheet.getWorkbook(), cf);
-	}
+    /**
+     * gets Conditional Formatting object at a particular index
+     *
+     * @param index
+     *			of the Conditional Formatting object to fetch
+     * @return Conditional Formatting object
+     */
+    public HSSFConditionalFormatting getConditionalFormattingAt(int index) {
+        CFRecordsAggregate cf = _conditionalFormattingTable.get(index);
+        if (cf == null) {
+            return null;
+        }
+        return new HSSFConditionalFormatting(_sheet, cf);
+    }
 
-	/**
-	* @return number of Conditional Formatting objects of the sheet
-	*/
-	public int getNumConditionalFormattings() {
-		return _conditionalFormattingTable.size();
-	}
+    /**
+     * @return number of Conditional Formatting objects of the sheet
+     */
+    public int getNumConditionalFormattings() {
+        return _conditionalFormattingTable.size();
+    }
 
-	/**
-	* removes a Conditional Formatting object by index
-	* @param index of a Conditional Formatting object to remove
-	*/
-	public void removeConditionalFormatting(int index) {
-		_conditionalFormattingTable.remove(index);
-	}
+    /**
+     * removes a Conditional Formatting object by index
+     * @param index of a Conditional Formatting object to remove
+     */
+    public void removeConditionalFormatting(int index) {
+        _conditionalFormattingTable.remove(index);
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index 503ed64..65ec1a3 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -65,6 +65,7 @@
 import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
 import org.apache.poi.hssf.record.common.UnicodeString;
 import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.poifs.crypt.Decryptor;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.EntryUtils;
@@ -205,6 +206,19 @@
     public HSSFWorkbook(POIFSFileSystem fs) throws IOException {
         this(fs,true);
     }
+    /**
+     * Given a POI POIFSFileSystem object, read in its Workbook along
+     *  with all related nodes, and populate the high and low level models.
+     * <p>This calls {@link #HSSFWorkbook(POIFSFileSystem, boolean)} with
+     *  preserve nodes set to true. 
+     * 
+     * @see #HSSFWorkbook(POIFSFileSystem, boolean)
+     * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
+     * @exception IOException if the stream cannot be read
+     */
+    public HSSFWorkbook(NPOIFSFileSystem fs) throws IOException {
+        this(fs.getRoot(),true);
+    }
 
     /**
      * Given a POI POIFSFileSystem object, read in its Workbook and populate 
@@ -248,7 +262,7 @@
         
         // check for an encrypted .xlsx file - they get OLE2 wrapped
         try {
-        	directory.getEntry("EncryptedPackage");
+        	directory.getEntry(Decryptor.DEFAULT_POIFS_ENTRY);
         	throw new EncryptedDocumentException("The supplied spreadsheet seems to be an Encrypted .xlsx file. " +
         			"It must be decrypted before use by XSSF, it cannot be used by HSSF");
         } catch (FileNotFoundException e) {
@@ -378,7 +392,7 @@
     public HSSFWorkbook(InputStream s, boolean preserveNodes)
             throws IOException
     {
-        this(new POIFSFileSystem(s), preserveNodes);
+        this(new NPOIFSFileSystem(s).getRoot(), preserveNodes);
     }
 
     /**
@@ -1276,7 +1290,7 @@
             throws IOException
     {
         byte[] bytes = getBytes();
-        POIFSFileSystem fs = new POIFSFileSystem();
+        NPOIFSFileSystem fs = new NPOIFSFileSystem();
 
         // For tracking what we've written out, used if we're
         //  going to be preserving nodes
@@ -1843,7 +1857,7 @@
     throws IOException {
     	// check if we were created by POIFS otherwise create a new dummy POIFS for storing the package data
     	if (directory == null) {
-    		directory = new POIFSFileSystem().getRoot();
+    		directory = new NPOIFSFileSystem().getRoot();
     		preserveNodes = true;
     	}
     	
diff --git a/src/java/org/apache/poi/hssf/util/HSSFColor.java b/src/java/org/apache/poi/hssf/util/HSSFColor.java
index f438e1b..d7a1cb5 100644
--- a/src/java/org/apache/poi/hssf/util/HSSFColor.java
+++ b/src/java/org/apache/poi/hssf/util/HSSFColor.java
@@ -204,6 +204,13 @@
     {
         return BLACK.hexString;
     }
+    
+    public static HSSFColor toHSSFColor(Color color) {
+        if (color != null && !(color instanceof HSSFColor)) {
+            throw new IllegalArgumentException("Only HSSFColor objects are supported");
+        }
+        return (HSSFColor)color;
+    }
 
     /**
      * Class BLACK
diff --git a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
index 8a2bf00..2c5716d 100644
--- a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
+++ b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
@@ -16,6 +16,8 @@
 ==================================================================== */

 package org.apache.poi.poifs.crypt;

 

+import static org.apache.poi.poifs.crypt.Decryptor.DEFAULT_POIFS_ENTRY;

+

 import java.io.File;

 import java.io.FileInputStream;

 import java.io.FileOutputStream;

@@ -132,8 +134,8 @@
             super.close();

             

             int oleStreamSize = (int)(fileOut.length()+LittleEndianConsts.LONG_SIZE);

-            calculateChecksum(fileOut, oleStreamSize);

-            dir.createDocument("EncryptedPackage", oleStreamSize, new EncryptedPackageWriter());

+            calculateChecksum(fileOut, (int)_pos);

+            dir.createDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, new EncryptedPackageWriter());

             createEncryptionInfoEntry(dir, fileOut);

         } catch (GeneralSecurityException e) {

             throw new IOException(e);

diff --git a/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java b/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java
index 0c80c6c..f6477fb 100644
--- a/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java
+++ b/src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java
@@ -36,7 +36,7 @@
     public static void addDefaultDataSpace(DirectoryEntry dir) throws IOException {

         DataSpaceMapEntry dsme = new DataSpaceMapEntry(

                 new int[]{ 0 }

-              , new String[]{ "EncryptedPackage" }

+              , new String[]{ Decryptor.DEFAULT_POIFS_ENTRY }

               , "StrongEncryptionDataSpace"

           );

           DataSpaceMap dsm = new DataSpaceMap(new DataSpaceMapEntry[]{dsme});

diff --git a/src/java/org/apache/poi/poifs/crypt/Decryptor.java b/src/java/org/apache/poi/poifs/crypt/Decryptor.java
index af44929..eb94dca 100644
--- a/src/java/org/apache/poi/poifs/crypt/Decryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/Decryptor.java
@@ -25,10 +25,12 @@
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 public abstract class Decryptor {
     public static final String DEFAULT_PASSWORD="VelvetSweatshop";
+    public static final String DEFAULT_POIFS_ENTRY="EncryptedPackage";
     
     protected final EncryptionInfoBuilder builder;
     private SecretKey secretKey;
@@ -83,7 +85,9 @@
     public InputStream getDataStream(NPOIFSFileSystem fs) throws IOException, GeneralSecurityException {
         return getDataStream(fs.getRoot());
     }
-
+    public InputStream getDataStream(OPOIFSFileSystem fs) throws IOException, GeneralSecurityException {
+        return getDataStream(fs.getRoot());
+    }
     public InputStream getDataStream(POIFSFileSystem fs) throws IOException, GeneralSecurityException {
         return getDataStream(fs.getRoot());
     }
diff --git a/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java b/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java
index 0418bef..3aafb90 100644
--- a/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java
+++ b/src/java/org/apache/poi/poifs/crypt/EncryptionInfo.java
@@ -26,6 +26,7 @@
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
@@ -68,14 +69,27 @@
     public static BitField flagAES = BitFieldFactory.getInstance(0x20);
     
     
+    /**
+     * Opens for decryption
+     */
     public EncryptionInfo(POIFSFileSystem fs) throws IOException {
        this(fs.getRoot());
     }
-    
+    /**
+     * Opens for decryption
+     */
+    public EncryptionInfo(OPOIFSFileSystem fs) throws IOException {
+       this(fs.getRoot());
+    }
+    /**
+     * Opens for decryption
+     */
     public EncryptionInfo(NPOIFSFileSystem fs) throws IOException {
        this(fs.getRoot());
     }
-    
+    /**
+     * Opens for decryption
+     */
     public EncryptionInfo(DirectoryNode dir) throws IOException {
         this(dir.createDocumentInputStream("EncryptionInfo"), false);
     }
@@ -131,7 +145,7 @@
     }
     
     /**
-     * @deprecated use constructor without fs parameter
+     * @deprecated Use {@link #EncryptionInfo(EncryptionMode)} (fs parameter no longer required)
      */
     @Deprecated
     public EncryptionInfo(POIFSFileSystem fs, EncryptionMode encryptionMode) {
@@ -139,7 +153,7 @@
     }
      
     /**
-     * @deprecated use constructor without fs parameter
+     * @deprecated Use {@link #EncryptionInfo(EncryptionMode)} (fs parameter no longer required)
      */
     @Deprecated
     public EncryptionInfo(NPOIFSFileSystem fs, EncryptionMode encryptionMode) {
@@ -147,7 +161,7 @@
     }
      
     /**
-     * @deprecated use constructor without dir parameter
+     * @deprecated Use {@link #EncryptionInfo(EncryptionMode)} (dir parameter no longer required)
      */
     @Deprecated
     public EncryptionInfo(DirectoryNode dir, EncryptionMode encryptionMode) {
@@ -155,7 +169,7 @@
     }
     
     /**
-     * @deprecated use constructor without fs parameter
+     * @deprecated use {@link #EncryptionInfo(EncryptionMode, CipherAlgorithm, HashAlgorithm, int, int, ChainingMode)}
      */
     @Deprecated
     public EncryptionInfo(
@@ -171,7 +185,7 @@
     }
     
     /**
-     * @deprecated use constructor without fs parameter
+     * @deprecated use {@link #EncryptionInfo(EncryptionMode, CipherAlgorithm, HashAlgorithm, int, int, ChainingMode)}
      */
     @Deprecated
     public EncryptionInfo(
@@ -187,7 +201,7 @@
     }
         
     /**
-     * @deprecated use constructor without dir parameter
+     * @deprecated use {@link #EncryptionInfo(EncryptionMode, CipherAlgorithm, HashAlgorithm, int, int, ChainingMode)}
      */
     @Deprecated
     public EncryptionInfo(
@@ -202,6 +216,11 @@
         this(encryptionMode, cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode);
     }        
 
+    /**
+     * Prepares for encryption, using the given Encryption Mode, and
+     *  all other parameters as default.
+     * @see #EncryptionInfo(EncryptionMode, CipherAlgorithm, HashAlgorithm, int, int, ChainingMode)
+     */
     public EncryptionInfo(EncryptionMode encryptionMode) {
         this(encryptionMode, null, null, -1, -1, null);
     }
diff --git a/src/java/org/apache/poi/poifs/crypt/Encryptor.java b/src/java/org/apache/poi/poifs/crypt/Encryptor.java
index abfd693..d40f8ae 100644
--- a/src/java/org/apache/poi/poifs/crypt/Encryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/Encryptor.java
@@ -24,9 +24,11 @@
 

 import org.apache.poi.poifs.filesystem.DirectoryNode;

 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;

+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;

 import org.apache.poi.poifs.filesystem.POIFSFileSystem;

 

 public abstract class Encryptor {

+    protected static final String DEFAULT_POIFS_ENTRY = Decryptor.DEFAULT_POIFS_ENTRY;

     private SecretKey secretKey;

     

     /**

@@ -50,7 +52,9 @@
     public OutputStream getDataStream(NPOIFSFileSystem fs) throws IOException, GeneralSecurityException {

         return getDataStream(fs.getRoot());

     }

-

+    public OutputStream getDataStream(OPOIFSFileSystem fs) throws IOException, GeneralSecurityException {

+        return getDataStream(fs.getRoot());

+    }

     public OutputStream getDataStream(POIFSFileSystem fs) throws IOException, GeneralSecurityException {

         return getDataStream(fs.getRoot());

     }

diff --git a/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java b/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java
index 40eab54..a2d3d6f 100644
--- a/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java
@@ -118,7 +118,7 @@
 

     public InputStream getDataStream(DirectoryNode dir) throws IOException,

             GeneralSecurityException {

-        DocumentInputStream dis = dir.createDocumentInputStream("EncryptedPackage");

+        DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY);

         _length = dis.readLong();

         BinaryRC4CipherInputStream cipherStream = new BinaryRC4CipherInputStream(dis, _length);

         return cipherStream;

@@ -131,4 +131,4 @@
         

         return _length;

     }

-}
\ No newline at end of file
+}

diff --git a/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java b/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java
index c1ae13c..1e470d7 100644
--- a/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java
@@ -40,7 +40,7 @@
 import org.apache.poi.poifs.filesystem.DirectoryNode;

 import org.apache.poi.poifs.filesystem.DocumentInputStream;

 import org.apache.poi.poifs.filesystem.DocumentNode;

-import org.apache.poi.poifs.filesystem.POIFSFileSystem;

+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;

 import org.apache.poi.util.BitField;

 import org.apache.poi.util.BitFieldFactory;

 import org.apache.poi.util.BoundedInputStream;

@@ -200,7 +200,7 @@
     @SuppressWarnings("unused")

     public InputStream getDataStream(DirectoryNode dir)

     throws IOException, GeneralSecurityException {

-        POIFSFileSystem fsOut = new POIFSFileSystem();

+        NPOIFSFileSystem fsOut = new NPOIFSFileSystem();

         DocumentNode es = (DocumentNode) dir.getEntry("EncryptedSummary");

         DocumentInputStream dis = dir.createDocumentInputStream(es);

         ByteArrayOutputStream bos = new ByteArrayOutputStream();

@@ -240,6 +240,7 @@
         sbis = null;

         bos.reset();

         fsOut.writeFilesystem(bos);

+        fsOut.close();

         _length = bos.size();

         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

         return bis;

diff --git a/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java b/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java
index 2b2c75b..1d6ddd3 100644
--- a/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java
@@ -123,7 +123,7 @@
     }
 
     public InputStream getDataStream(DirectoryNode dir) throws IOException {
-        DocumentInputStream dis = dir.createDocumentInputStream("EncryptedPackage");
+        DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY);
 
         _length = dis.readLong();
 
diff --git a/src/java/org/apache/poi/poifs/crypt/standard/StandardEncryptor.java b/src/java/org/apache/poi/poifs/crypt/standard/StandardEncryptor.java
index 7049c71..ae6304f 100644
--- a/src/java/org/apache/poi/poifs/crypt/standard/StandardEncryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/standard/StandardEncryptor.java
@@ -166,7 +166,7 @@
         

         void writeToPOIFS() throws IOException {

             int oleStreamSize = (int)(fileOut.length()+LittleEndianConsts.LONG_SIZE);

-            dir.createDocument("EncryptedPackage", oleStreamSize, this);

+            dir.createDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, this);

             // TODO: any properties???

         }

     

diff --git a/src/java/org/apache/poi/poifs/dev/POIFSDump.java b/src/java/org/apache/poi/poifs/dev/POIFSDump.java
index ace19d8..ce7d9e4 100644
--- a/src/java/org/apache/poi/poifs/dev/POIFSDump.java
+++ b/src/java/org/apache/poi/poifs/dev/POIFSDump.java
@@ -16,27 +16,54 @@
 ==================================================================== */
 package org.apache.poi.poifs.dev;
 
-import org.apache.poi.poifs.filesystem.*;
-
-import java.io.FileInputStream;
 import java.io.File;
-import java.io.IOException;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
 import java.util.Iterator;
 
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.poifs.filesystem.DocumentNode;
+import org.apache.poi.poifs.filesystem.Entry;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSStream;
+import org.apache.poi.poifs.property.NPropertyTable;
+import org.apache.poi.poifs.storage.HeaderBlock;
+
 /**
- *
  * Dump internal structure of a OLE2 file into file system
- *
- * @author Yegor Kozlov
  */
 public class POIFSDump {
-
     public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            System.err.println("Must specify at least one file to dump");
+            System.exit(1);
+        }
+        
+        boolean dumpProps = false, dumpMini = false;
         for (int i = 0; i < args.length; i++) {
+            if (args[i].equalsIgnoreCase("-dumprops") ||
+                args[i].equalsIgnoreCase("-dump-props") ||
+                args[i].equalsIgnoreCase("-dump-properties")) {
+                dumpProps = true;
+                continue;
+            }
+            if (args[i].equalsIgnoreCase("-dumpmini") ||
+                args[i].equalsIgnoreCase("-dump-mini") ||
+                args[i].equalsIgnoreCase("-dump-ministream") ||
+                args[i].equalsIgnoreCase("-dump-mini-stream")) {
+                dumpMini = true;
+                continue;
+            }
+            
             System.out.println("Dumping " + args[i]);
             FileInputStream is = new FileInputStream(args[i]);
-            POIFSFileSystem fs = new POIFSFileSystem(is);
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(is);
             is.close();
 
             DirectoryEntry root = fs.getRoot();
@@ -44,13 +71,39 @@
             file.mkdir();
 
             dump(root, file);
+            
+            if (dumpProps) {
+                HeaderBlock header = getHeaderBlock(fs);
+                dump(fs, header.getPropertyStart(), "properties", file);
+            }
+            if (dumpMini) {
+                NPropertyTable props = getPropertyTable(fs);
+                int startBlock = props.getRoot().getStartBlock(); 
+                if (startBlock == POIFSConstants.END_OF_CHAIN) {
+                    System.err.println("No Mini Stream in file");
+                } else {
+                    dump(fs, startBlock, "mini-stream", file);
+                }
+            }
         }
    }
-
+    
+    protected static HeaderBlock getHeaderBlock(NPOIFSFileSystem fs) throws Exception {
+        Field headerF = NPOIFSFileSystem.class.getDeclaredField("_header");
+        headerF.setAccessible(true);
+        HeaderBlock header = (HeaderBlock)headerF.get(fs);
+        return header;
+    }
+    protected static NPropertyTable getPropertyTable(NPOIFSFileSystem fs) throws Exception {
+        Field ptF = NPOIFSFileSystem.class.getDeclaredField("_property_table");
+        ptF.setAccessible(true);
+        NPropertyTable table = (NPropertyTable)ptF.get(fs);
+        return table;
+    }
 
     public static void dump(DirectoryEntry root, File parent) throws IOException {
-        for(Iterator it = root.getEntries(); it.hasNext();){
-            Entry entry = (Entry)it.next();
+        for(Iterator<Entry> it = root.getEntries(); it.hasNext();){
+            Entry entry = it.next();
             if(entry instanceof DocumentNode){
                 DocumentNode node = (DocumentNode)entry;
                 DocumentInputStream is = new DocumentInputStream(node);
@@ -58,9 +111,12 @@
                 is.read(bytes);
                 is.close();
 
-                FileOutputStream out = new FileOutputStream(new File(parent, node.getName().trim()));
-                out.write(bytes);
-                out.close();
+                OutputStream out = new FileOutputStream(new File(parent, node.getName().trim()));
+                try {
+                	out.write(bytes);
+                } finally {
+                	out.close();
+                }
             } else if (entry instanceof DirectoryEntry){
                 DirectoryEntry dir = (DirectoryEntry)entry;
                 File file = new File(parent, entry.getName());
@@ -71,4 +127,17 @@
             }
         }
     }
+    public static void dump(NPOIFSFileSystem fs, int startBlock, String name, File parent) throws IOException {
+        File file = new File(parent, name);
+        FileOutputStream out = new FileOutputStream(file);
+        NPOIFSStream stream = new NPOIFSStream(fs, startBlock);
+        
+        byte[] b = new byte[fs.getBigBlockSize()];
+        for (ByteBuffer bb : stream) {
+            int len = bb.remaining();
+            bb.get(b);
+            out.write(b, 0, len);
+        }
+        out.close();
+    }
 }
diff --git a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java
index 78ed986..e321c8b 100644
--- a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java
+++ b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java
@@ -24,9 +24,10 @@
 
 import org.apache.poi.poifs.common.POIFSBigBlockSize;
 import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.property.DirectoryProperty;
+import org.apache.poi.poifs.property.Property;
 import org.apache.poi.poifs.property.PropertyTable;
 import org.apache.poi.poifs.storage.BlockAllocationTableReader;
-import org.apache.poi.poifs.storage.BlockList;
 import org.apache.poi.poifs.storage.HeaderBlock;
 import org.apache.poi.poifs.storage.ListManagedBlock;
 import org.apache.poi.poifs.storage.RawDataBlockList;
@@ -42,111 +43,146 @@
  *  down the source of corruption in a file.
  */
 public class POIFSHeaderDumper {
-	/**
-	 * Display the entries of multiple POIFS files
-	 *
-	 * @param args the names of the files to be displayed
-	 */
-	public static void main(final String args[]) throws Exception {
-		if (args.length == 0) {
-			System.err.println("Must specify at least one file to view");
-			System.exit(1);
-		}
+    /**
+     * Display the entries of multiple POIFS files
+     *
+     * @param args the names of the files to be displayed
+     */
+    public static void main(final String args[]) throws Exception {
+        if (args.length == 0) {
+            System.err.println("Must specify at least one file to view");
+            System.exit(1);
+        }
 
-		for (int j = 0; j < args.length; j++) {
-		   viewFile(args[j]);
-		}
-	}
+        for (int j = 0; j < args.length; j++) {
+            viewFile(args[j]);
+        }
+    }
 
-	public static void viewFile(final String filename) throws Exception {
-		InputStream inp = new FileInputStream(filename);
-		
-		// Header
-		HeaderBlock header_block = new HeaderBlock(inp);
-		displayHeader(header_block);
-		
-		// Raw blocks
-      POIFSBigBlockSize bigBlockSize = header_block.getBigBlockSize();
-      RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize);
-      displayRawBlocksSummary(data_blocks);
-      
-      // Main FAT Table
-      BlockAllocationTableReader batReader =
-         new BlockAllocationTableReader(
-            header_block.getBigBlockSize(),
-            header_block.getBATCount(),
-            header_block.getBATArray(),
-            header_block.getXBATCount(),
-            header_block.getXBATIndex(),
-            data_blocks);
-      displayBATReader(batReader);
+    public static void viewFile(final String filename) throws Exception {
+        System.out.println("Dumping headers from: " + filename);
+        InputStream inp = new FileInputStream(filename);
 
-      // Properties Table
-      PropertyTable properties =
-         new PropertyTable(header_block, data_blocks);
-      
-      // Mini Fat
-      BlockList sbat = 
-         SmallBlockTableReader.getSmallDocumentBlocks(
-               bigBlockSize, data_blocks, properties.getRoot(),
-               header_block.getSBATStart()
-         );
-   }
+        // Header
+        HeaderBlock header_block = new HeaderBlock(inp);
+        displayHeader(header_block);
 
-	public static void displayHeader(HeaderBlock header_block) throws Exception {
-	   System.out.println("Header Details:");
-	   System.out.println(" Block size: " + header_block.getBigBlockSize().getBigBlockSize());
-      System.out.println(" BAT (FAT) header blocks: " + header_block.getBATArray().length);
-      System.out.println(" BAT (FAT) block count: " + header_block.getBATCount());
-      System.out.println(" XBAT (FAT) block count: " + header_block.getXBATCount());
-      System.out.println(" XBAT (FAT) block 1 at: " + header_block.getXBATIndex());
-      System.out.println(" SBAT (MiniFAT) block count: " + header_block.getSBATCount());
-      System.out.println(" SBAT (MiniFAT) block 1 at: " + header_block.getSBATStart());
-      System.out.println(" Property table at: " + header_block.getPropertyStart());
-      System.out.println("");
-	}
+        // Raw blocks
+        POIFSBigBlockSize bigBlockSize = header_block.getBigBlockSize();
+        RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize);
+        displayRawBlocksSummary(data_blocks);
 
-   public static void displayRawBlocksSummary(RawDataBlockList data_blocks) throws Exception {
-      System.out.println("Raw Blocks Details:");
-      System.out.println(" Number of blocks: " + data_blocks.blockCount());
-      
-      Method gbm = data_blocks.getClass().getSuperclass().getDeclaredMethod("get", int.class);
-      gbm.setAccessible(true);
-      
-      for(int i=0; i<Math.min(16, data_blocks.blockCount()); i++) {
-         ListManagedBlock block = (ListManagedBlock)gbm.invoke(data_blocks, Integer.valueOf(i));
-         byte[] data = new byte[Math.min(48, block.getData().length)];
-         System.arraycopy(block.getData(), 0, data, 0, data.length);
-         
-         System.out.println(" Block #" + i + ":");
-         System.out.println(HexDump.dump(data, 0, 0));
-      }
-      
-      System.out.println("");
-   }
-   
-   public static void displayBATReader(BlockAllocationTableReader batReader) throws Exception {
-      System.out.println("Sectors, as referenced from the FAT:");
-      Field entriesF = batReader.getClass().getDeclaredField("_entries");
-      entriesF.setAccessible(true);
-      IntList entries = (IntList)entriesF.get(batReader);
-      
-      for(int i=0; i<entries.size(); i++) {
-         int bn = entries.get(i);
-         String bnS = Integer.toString(bn);
-         if(bn == POIFSConstants.END_OF_CHAIN) {
-            bnS = "End Of Chain";
-         } else if(bn == POIFSConstants.DIFAT_SECTOR_BLOCK) {
-            bnS = "DI Fat Block";
-         } else if(bn == POIFSConstants.FAT_SECTOR_BLOCK) {
-            bnS = "Normal Fat Block";
-         } else if(bn == POIFSConstants.UNUSED_BLOCK) {
-            bnS = "Block Not Used (Free)";
-         }
-         
-         System.out.println("  Block  # " + i + " -> " + bnS);
-      }
-      
-      System.out.println("");
-   }
+        // Main FAT Table
+        BlockAllocationTableReader batReader =
+                new BlockAllocationTableReader(
+                        header_block.getBigBlockSize(),
+                        header_block.getBATCount(),
+                        header_block.getBATArray(),
+                        header_block.getXBATCount(),
+                        header_block.getXBATIndex(),
+                        data_blocks);
+        displayBATReader("Big Blocks", batReader);
+
+        // Properties Table
+        PropertyTable properties =
+                new PropertyTable(header_block, data_blocks);
+
+        // Mini Fat
+        BlockAllocationTableReader sbatReader = 
+                SmallBlockTableReader._getSmallDocumentBlockReader(
+                        bigBlockSize, data_blocks, properties.getRoot(),
+                        header_block.getSBATStart()
+                        );
+        displayBATReader("Small Blocks", sbatReader);
+
+        // Summary of the properties
+        displayPropertiesSummary(properties);
+    }
+
+    public static void displayHeader(HeaderBlock header_block) throws Exception {
+        System.out.println("Header Details:");
+        System.out.println(" Block size: " + header_block.getBigBlockSize().getBigBlockSize());
+        System.out.println(" BAT (FAT) header blocks: " + header_block.getBATArray().length);
+        System.out.println(" BAT (FAT) block count: " + header_block.getBATCount());
+        if (header_block.getBATCount() > 0) 
+            System.out.println(" BAT (FAT) block 1 at: " + header_block.getBATArray()[0]);
+        System.out.println(" XBAT (FAT) block count: " + header_block.getXBATCount());
+        System.out.println(" XBAT (FAT) block 1 at: " + header_block.getXBATIndex());
+        System.out.println(" SBAT (MiniFAT) block count: " + header_block.getSBATCount());
+        System.out.println(" SBAT (MiniFAT) block 1 at: " + header_block.getSBATStart());
+        System.out.println(" Property table at: " + header_block.getPropertyStart());
+        System.out.println("");
+    }
+
+    public static void displayRawBlocksSummary(RawDataBlockList data_blocks) throws Exception {
+        System.out.println("Raw Blocks Details:");
+        System.out.println(" Number of blocks: " + data_blocks.blockCount());
+
+        Method gbm = data_blocks.getClass().getSuperclass().getDeclaredMethod("get", int.class);
+        gbm.setAccessible(true);
+
+        for(int i=0; i<Math.min(16, data_blocks.blockCount()); i++) {
+            ListManagedBlock block = (ListManagedBlock)gbm.invoke(data_blocks, Integer.valueOf(i));
+            byte[] data = new byte[Math.min(48, block.getData().length)];
+            System.arraycopy(block.getData(), 0, data, 0, data.length);
+
+            System.out.println(" Block #" + i + ":");
+            System.out.println(HexDump.dump(data, 0, 0));
+        }
+
+        System.out.println("");
+    }
+
+    public static void displayBATReader(String type, BlockAllocationTableReader batReader) throws Exception {
+        System.out.println("Sectors, as referenced from the "+type+" FAT:");
+        Field entriesF = batReader.getClass().getDeclaredField("_entries");
+        entriesF.setAccessible(true);
+        IntList entries = (IntList)entriesF.get(batReader);
+
+        for(int i=0; i<entries.size(); i++) {
+            int bn = entries.get(i);
+            String bnS = Integer.toString(bn);
+            if(bn == POIFSConstants.END_OF_CHAIN) {
+                bnS = "End Of Chain";
+            } else if(bn == POIFSConstants.DIFAT_SECTOR_BLOCK) {
+                bnS = "DI Fat Block";
+            } else if(bn == POIFSConstants.FAT_SECTOR_BLOCK) {
+                bnS = "Normal Fat Block";
+            } else if(bn == POIFSConstants.UNUSED_BLOCK) {
+                bnS = "Block Not Used (Free)";
+            }
+
+            System.out.println("  Block  # " + i + " -> " + bnS);
+        }
+
+        System.out.println("");
+    }
+
+    public static void displayPropertiesSummary(PropertyTable properties) {
+        System.out.println("Mini Stream starts at " + properties.getRoot().getStartBlock());
+        System.out.println("Mini Stream length is " + properties.getRoot().getSize());
+        System.out.println();
+        
+        System.out.println("Properties and their block start:");
+        displayProperties(properties.getRoot(), "");
+        System.out.println("");
+    }
+    public static void displayProperties(DirectoryProperty prop, String indent) {
+        String nextIndent = indent + "  ";
+        System.out.println(indent + "-> " + prop.getName());
+        for (Property cp : prop) {
+            if (cp instanceof DirectoryProperty) {
+                displayProperties((DirectoryProperty)cp, nextIndent);
+            } else {
+                System.out.println(nextIndent + "=> " + cp.getName());
+                System.out.print(nextIndent + "   " + cp.getSize() + " bytes in ");
+                if (cp.shouldUseSmallBlocks()) {
+                    System.out.print("mini");
+                } else {
+                    System.out.print("main");
+                }
+                System.out.println(" stream, starts at " + cp.getStartBlock());
+            }
+        }
+    }
 }
diff --git a/src/java/org/apache/poi/poifs/dev/POIFSViewer.java b/src/java/org/apache/poi/poifs/dev/POIFSViewer.java
index 8b81734..4614376 100644
--- a/src/java/org/apache/poi/poifs/dev/POIFSViewer.java
+++ b/src/java/org/apache/poi/poifs/dev/POIFSViewer.java
@@ -19,12 +19,12 @@
 
 package org.apache.poi.poifs.dev;
 
-import java.io.FileInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 
 /**
  * A simple viewer for POIFS files
@@ -76,10 +76,10 @@
         try
         {
             POIFSViewable fs      =
-                new POIFSFileSystem(new FileInputStream(filename));
-            List<String>          strings = POIFSViewEngine.inspectViewable(fs, true,
+                new NPOIFSFileSystem(new File(filename));
+            List<String>  strings = POIFSViewEngine.inspectViewable(fs, true,
                                         0, "  ");
-            Iterator<String>      iter    = strings.iterator();
+            Iterator<String> iter = strings.iterator();
 
             while (iter.hasNext())
             {
diff --git a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
index 5675275..a288709 100644
--- a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
+++ b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
@@ -24,7 +24,7 @@
 import java.util.*;
 
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
-import org.apache.poi.poifs.filesystem.POIFSDocument;
+import org.apache.poi.poifs.filesystem.OPOIFSDocument;
 import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
 import org.apache.poi.poifs.property.DirectoryProperty;
 import org.apache.poi.poifs.property.Property;
@@ -240,19 +240,19 @@
 
                 if (listeners.hasNext())
                 {
-                    int           size     = property.getSize();
-                    POIFSDocument document = null;
+                    int            size     = property.getSize();
+                    OPOIFSDocument document = null;
 
                     if (property.shouldUseSmallBlocks())
                     {
                         document =
-                            new POIFSDocument(name, small_blocks
+                            new OPOIFSDocument(name, small_blocks
                                 .fetchBlocks(startBlock, -1), size);
                     }
                     else
                     {
                         document =
-                            new POIFSDocument(name, big_blocks
+                            new OPOIFSDocument(name, big_blocks
                                 .fetchBlocks(startBlock, -1), size);
                     }
                     while (listeners.hasNext())
diff --git a/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java b/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
index 8d39bbf..9be71a5 100644
--- a/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
+++ b/src/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
@@ -37,8 +37,6 @@
 
 /**
  * Simple implementation of DirectoryEntry
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
 public class DirectoryNode
     extends EntryNode
@@ -50,9 +48,9 @@
     // Our list of entries, kept sorted to preserve order
     private ArrayList<Entry> _entries;
 
-   // Only one of these two will exist
-    // the POIFSFileSystem we belong to
-    private POIFSFileSystem   _ofilesystem;
+    // Only one of these two will exist
+    // the OPOIFSFileSystem we belong to
+    private OPOIFSFileSystem   _ofilesystem;
     // the NPOIFSFileSytem we belong to
     private NPOIFSFileSystem  _nfilesystem;
 
@@ -64,11 +62,11 @@
      * is intended strictly for the internal use of this package
      *
      * @param property the DirectoryProperty for this DirectoryEntry
-     * @param filesystem the POIFSFileSystem we belong to
+     * @param filesystem the OPOIFSFileSystem we belong to
      * @param parent the parent of this entry
      */
     DirectoryNode(final DirectoryProperty property,
-                  final POIFSFileSystem filesystem,
+                  final OPOIFSFileSystem filesystem,
                   final DirectoryNode parent)
     {
        this(property, parent, filesystem, (NPOIFSFileSystem)null);
@@ -86,12 +84,12 @@
                   final NPOIFSFileSystem nfilesystem,
                   final DirectoryNode parent)
     {
-       this(property, parent, (POIFSFileSystem)null, nfilesystem);
+       this(property, parent, (OPOIFSFileSystem)null, nfilesystem);
     }
 
     private DirectoryNode(final DirectoryProperty property,
                           final DirectoryNode parent,
-                          final POIFSFileSystem ofilesystem,
+                          final OPOIFSFileSystem ofilesystem,
                           final NPOIFSFileSystem nfilesystem)
     {
         super(property, parent);
@@ -148,12 +146,24 @@
     /**
      * @return the filesystem that this belongs to
      */
-    public POIFSFileSystem getFileSystem()
+    public NPOIFSFileSystem getFileSystem()
+    {
+        return _nfilesystem;
+    }
+
+    /**
+     * If this is OPOIFS based, return the NPOIFSFileSystem
+     *  that this belong to, otherwise Null if NPOIFS based
+     * @return the filesystem that this belongs to
+     */
+    public OPOIFSFileSystem getOFileSystem()
     {
         return _ofilesystem;
     }
 
     /**
+     * If this is NPOIFS based, return the NPOIFSFileSystem
+     *  that this belong to, otherwise Null if OPOIFS based
      * @return the filesystem that this belongs to
      */
     public NPOIFSFileSystem getNFileSystem()
@@ -210,7 +220,7 @@
      *
      * @exception IOException
      */
-    DocumentEntry createDocument(final POIFSDocument document)
+    DocumentEntry createDocument(final OPOIFSDocument document)
         throws IOException
     {
         DocumentProperty property = document.getDocumentProperty();
@@ -411,7 +421,7 @@
         if(_nfilesystem != null) {
            return createDocument(new NPOIFSDocument(name, _nfilesystem, stream));
         } else {
-           return createDocument(new POIFSDocument(name, stream));
+           return createDocument(new OPOIFSDocument(name, stream));
         }
     }
 
@@ -434,7 +444,7 @@
         if(_nfilesystem != null) {
             return createDocument(new NPOIFSDocument(name, size, _nfilesystem, writer));
          } else {
-            return createDocument(new POIFSDocument(name, size, _path, writer));
+            return createDocument(new OPOIFSDocument(name, size, _path, writer));
          }
     }
 
diff --git a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
index 6c6b610..82959c7 100644
--- a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
+++ b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
@@ -58,7 +58,7 @@
 
 	   if(documentNode.getDocument() != null) {
 	      delegate = new ODocumentInputStream(document);
-	   } else if(parentNode.getFileSystem() != null) {
+	   } else if(parentNode.getOFileSystem() != null) {
 	      delegate = new ODocumentInputStream(document);
 	   } else if(parentNode.getNFileSystem() != null) {
 	      delegate = new NDocumentInputStream(document);
@@ -72,7 +72,7 @@
 	 * 
 	 * @param document the Document to be read
 	 */
-	public DocumentInputStream(POIFSDocument document) {
+	public DocumentInputStream(OPOIFSDocument document) {
 	   delegate = new ODocumentInputStream(document);
 	}
 
diff --git a/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java b/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java
index 9caafb7..7a5bf69 100644
--- a/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java
+++ b/src/java/org/apache/poi/poifs/filesystem/DocumentNode.java
@@ -27,18 +27,15 @@
 import org.apache.poi.poifs.property.DocumentProperty;
 
 /**
- * Simple implementation of DocumentEntry
- *
- * @author Marc Johnson (mjohnson at apache dot org)
+ * Simple implementation of DocumentEntry for OPOIFS
  */
-
 public class DocumentNode
     extends EntryNode
     implements DocumentEntry, POIFSViewable
 {
 
     // underlying POIFSDocument instance
-    private POIFSDocument _document;
+    private OPOIFSDocument _document;
 
     /**
      * create a DocumentNode. This method is not public by design; it
@@ -59,8 +56,7 @@
      *
      * @return the internal POIFSDocument
      */
-
-    POIFSDocument getDocument()
+    OPOIFSDocument getDocument()
     {
         return _document;
     }
diff --git a/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java b/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java
index 4bce064..d8a5556 100644
--- a/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java
+++ b/src/java/org/apache/poi/poifs/filesystem/EntryUtils.java
@@ -124,8 +124,21 @@
      * @param target
      *            is the target POIFS to copy to
      */
-    public static void copyNodes( POIFSFileSystem source,
-            POIFSFileSystem target ) throws IOException
+    public static void copyNodes( OPOIFSFileSystem source,
+            OPOIFSFileSystem target ) throws IOException
+    {
+        copyNodes( source.getRoot(), target.getRoot() );
+    }
+    /**
+     * Copies all nodes from one POIFS to the other
+     * 
+     * @param source
+     *            is the source POIFS to copy from
+     * @param target
+     *            is the target POIFS to copy to
+     */
+    public static void copyNodes( NPOIFSFileSystem source,
+            NPOIFSFileSystem target ) throws IOException
     {
         copyNodes( source.getRoot(), target.getRoot() );
     }
@@ -140,8 +153,26 @@
      * @param target is the target POIFS to copy to
      * @param excepts is a list of Entry Names to be excluded from the copy
      */
-    public static void copyNodes( POIFSFileSystem source,
-            POIFSFileSystem target, List<String> excepts ) throws IOException
+    public static void copyNodes( OPOIFSFileSystem source,
+            OPOIFSFileSystem target, List<String> excepts ) throws IOException
+    {
+        copyNodes(
+              new FilteringDirectoryNode(source.getRoot(), excepts),
+              new FilteringDirectoryNode(target.getRoot(), excepts)
+        );
+    }
+    /**
+     * Copies nodes from one POIFS to the other, minus the excepts.
+     * This delegates the filtering work to {@link FilteringDirectoryNode},
+     *  so excepts can be of the form "NodeToExclude" or
+     *  "FilteringDirectory/ExcludedChildNode"
+     * 
+     * @param source is the source POIFS to copy from
+     * @param target is the target POIFS to copy to
+     * @param excepts is a list of Entry Names to be excluded from the copy
+     */
+    public static void copyNodes( NPOIFSFileSystem source,
+            NPOIFSFileSystem target, List<String> excepts ) throws IOException
     {
         copyNodes(
               new FilteringDirectoryNode(source.getRoot(), excepts),
diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
index 7846ed0..c94e427 100644
--- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
+++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
@@ -23,6 +23,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -143,8 +144,17 @@
            os.write(buf, 0, readBytes);
        }
        
-       os.close();
+       // Pad to the end of the block with -1s
+       int usedInBlock = length % _block_size;
+       if (usedInBlock != 0 && usedInBlock != _block_size) {
+           int toBlockEnd = _block_size - usedInBlock;
+           byte[] padding = new byte[toBlockEnd];
+           Arrays.fill(padding, (byte)0xFF);
+           os.write(padding);
+       }
        
+       // Tidy and return the length
+       os.close();
        return length;
    }
    
diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
index f21f6a3..c27ba3c 100644
--- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
+++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
@@ -36,6 +36,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.poi.EmptyFileException;
 import org.apache.poi.poifs.common.POIFSBigBlockSize;
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
@@ -114,17 +115,18 @@
     {
        this(true);
        
-        // Mark us as having a single empty BAT at offset 0
+        // Reserve block 0 for the start of the Properties Table
+        // Create a single empty BAT, at pop that at offset 1
         _header.setBATCount(1);
-        _header.setBATArray(new int[] { 0 });
+        _header.setBATArray(new int[] { 1 });
         BATBlock bb = BATBlock.createEmptyBATBlock(bigBlockSize, false);
-        bb.setOurBlockIndex(0);
+        bb.setOurBlockIndex(1);
         _bat_blocks.add(bb);
 
-        setNextBlock(0, POIFSConstants.FAT_SECTOR_BLOCK);
-        setNextBlock(1, POIFSConstants.END_OF_CHAIN);
+        setNextBlock(0, POIFSConstants.END_OF_CHAIN);
+        setNextBlock(1, POIFSConstants.FAT_SECTOR_BLOCK);
 
-        _property_table.setStartBlock(POIFSConstants.END_OF_CHAIN);
+        _property_table.setStartBlock(0);
     }
 
     /**
@@ -210,6 +212,9 @@
        try {
           // Initialize the datasource
           if (srcFile != null) {
+              if (srcFile.length() == 0)
+                  throw new EmptyFileException();
+              
               FileBackedDataSource d = new FileBackedDataSource(srcFile, readOnly);
               channel = d.getChannel();
               _data = d;
@@ -236,7 +241,10 @@
           // TODO Decide if we can handle these better whilst
           //  still sticking to the iterator contract
           if(closeChannelOnError) {
-             channel.close();
+              if (channel != null) {
+                  channel.close();
+                  channel = null;
+              }
           }
           throw e;
        }
@@ -370,6 +378,15 @@
     }
     
     /**
+     * Checks if the supplied first 8 bytes of a stream / file
+     *  has a POIFS (OLE2) header.
+     */
+    public static boolean hasPOIFSHeader(byte[] header8Bytes) {
+        LongField signature = new LongField(HeaderBlockConstants._signature_offset, header8Bytes);
+        return (signature.get() == HeaderBlockConstants._signature);
+    }
+    
+    /**
      * Read and process the PropertiesTable and the
      *  FAT / XFAT blocks, so that we're ready to
      *  work with the file
@@ -420,7 +437,7 @@
        List<BATBlock> sbats = new ArrayList<BATBlock>();
        _mini_store     = new NPOIFSMiniStore(this, _property_table.getRoot(), sbats, _header);
        nextAt = _header.getSBATStart();
-       for(int i=0; i<_header.getSBATCount(); i++) {
+       for(int i=0; i<_header.getSBATCount() && nextAt != POIFSConstants.END_OF_CHAIN; i++) {
           loopDetector.claim(nextAt);
           ByteBuffer fatData = getBlockAt(nextAt);
           sfat = BATBlock.createBATBlock(bigBlockSize, fatData);
@@ -749,6 +766,10 @@
      *  to their backing blocks 
      */
     private void syncWithDataSource() throws IOException {
+        // Mini Stream + SBATs first, as mini-stream details have
+        //  to be stored in the Root Property
+        _mini_store.syncWithDataSource();
+        
         // Properties
         NPOIFSStream propStream = new NPOIFSStream(this, _header.getPropertyStart());
         _property_table.preWrite();
@@ -769,9 +790,6 @@
            ByteBuffer block = getBlockAt(bat.getOurBlockIndex());
            BlockAllocationTableWriter.writeBlock(bat, block);
         }
-       
-       // SBATs
-       _mini_store.syncWithDataSource();
     }
     
     /**
diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java
index 308ae15..b784058 100644
--- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java
+++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSMiniStore.java
@@ -242,12 +242,24 @@
     }
     
     /**
-     * Writes the SBATs to their backing blocks
+     * Writes the SBATs to their backing blocks, and updates
+     *  the mini-stream size in the properties. Stream size is
+     *  based on full blocks used, not the data within the streams
      */
     protected void syncWithDataSource() throws IOException {
-       for(BATBlock sbat : _sbat_blocks) {
+       int blocksUsed = 0;
+       for (BATBlock sbat : _sbat_blocks) {
           ByteBuffer block = _filesystem.getBlockAt(sbat.getOurBlockIndex());
           BlockAllocationTableWriter.writeBlock(sbat, block);
+          
+          if (!sbat.hasFreeSectors()) {
+              blocksUsed += _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();
+          } else {
+              blocksUsed += sbat.getUsedSectors(false);
+          }
        }
+       // Set the size on the root in terms of the number of SBAT blocks
+       // RootProperty.setSize does the sbat -> bytes conversion for us
+       _filesystem._get_property_table().getRoot().setSize(blocksUsed);
     }
 }
diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java
index 5d444b8..da24fc3 100644
--- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java
+++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSStream.java
@@ -256,8 +256,10 @@
             NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock);
             toFree.free(loopDetector);
             
-            // Mark the end of the stream
-            blockStore.setNextBlock(prevBlock, POIFSConstants.END_OF_CHAIN);
+            // Mark the end of the stream, if we have any data
+            if (prevBlock != POIFSConstants.END_OF_CHAIN) {
+                blockStore.setNextBlock(prevBlock, POIFSConstants.END_OF_CHAIN);
+            }
         }
    }
 }
diff --git a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java
index a1bc5da..858e2d9 100644
--- a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java
+++ b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java
@@ -23,9 +23,7 @@
 
 /**
  * This class provides methods to read a DocumentEntry managed by a
- * {@link POIFSFileSystem} instance.
- *
- * @author Marc Johnson (mjohnson at apache dot org)
+ * {@link OPOIFSFileSystem} instance.
  */
 public final class ODocumentInputStream extends DocumentInputStream {
 	/** current offset into the Document */
@@ -41,7 +39,7 @@
 	private boolean _closed;
 
 	/** the actual Document */
-	private POIFSDocument _document;
+	private OPOIFSDocument _document;
 
 	/** the data block containing the current stream pointer */
 	private DataInputBlock _currentBlock;
@@ -59,7 +57,7 @@
 			throw new IOException("Cannot open internal document storage");
 		}
 		DocumentNode documentNode = (DocumentNode)document;
-		if(documentNode.getDocument() == null) {
+		if (documentNode.getDocument() == null) {
          throw new IOException("Cannot open internal document storage");
 		}
 		      
@@ -76,7 +74,7 @@
 	 * 
 	 * @param document the Document to be read
 	 */
-	public ODocumentInputStream(POIFSDocument document) {
+	public ODocumentInputStream(OPOIFSDocument document) {
 		_current_offset = 0;
 		_marked_offset = 0;
 		_document_size = document.getSize();
diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java
similarity index 94%
rename from src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
rename to src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java
index c6b35fd..05b21ba 100644
--- a/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
+++ b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java
@@ -40,11 +40,10 @@
 import org.apache.poi.util.HexDump;
 
 /**
- * This class manages a document in the POIFS filesystem.
- *
- * @author Marc Johnson (mjohnson at apache dot org)
+ * This class manages a document in a old-style 
+ *  OPOIFS filesystem.
  */
-public final class POIFSDocument implements BATManaged, BlockWritable, POIFSViewable  {
+public final class OPOIFSDocument implements BATManaged, BlockWritable, POIFSViewable  {
 	private static final DocumentBlock[] EMPTY_BIG_BLOCK_ARRAY = { };
 	private static final SmallDocumentBlock[] EMPTY_SMALL_BLOCK_ARRAY = { };
 	private DocumentProperty _property;
@@ -63,7 +62,7 @@
 	 * @param blocks the big blocks making up the POIFSDocument
 	 * @param length the actual length of the POIFSDocument
 	 */
-	public POIFSDocument(String name, RawDataBlock[] blocks, int length) throws IOException {
+	public OPOIFSDocument(String name, RawDataBlock[] blocks, int length) throws IOException {
 		_size = length;
 		if(blocks.length == 0) {
 		   _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
@@ -104,7 +103,7 @@
 	 * @param blocks the small blocks making up the POIFSDocument
 	 * @param length the actual length of the POIFSDocument
 	 */
-	public POIFSDocument(String name, SmallDocumentBlock[] blocks, int length) {
+	public OPOIFSDocument(String name, SmallDocumentBlock[] blocks, int length) {
 		_size = length;
 		
 		if(blocks.length == 0) {
@@ -126,7 +125,7 @@
 	 * @param blocks the small blocks making up the POIFSDocument
 	 * @param length the actual length of the POIFSDocument
 	 */
-	public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) throws IOException {
+	public OPOIFSDocument(String name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) throws IOException {
 		_size = length;
 		_bigBigBlockSize = bigBlockSize;
 		_property = new DocumentProperty(name, _size);
@@ -139,7 +138,7 @@
 			_small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY);
 		}
 	}
-	public POIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException {
+	public OPOIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException {
 	   this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blocks, length);
 	}
 
@@ -149,7 +148,7 @@
 	 * @param name the name of the POIFSDocument
 	 * @param stream the InputStream we read data from
 	 */
-	public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, InputStream stream) throws IOException {
+	public OPOIFSDocument(String name, POIFSBigBlockSize bigBlockSize, InputStream stream) throws IOException {
 		List<DocumentBlock> blocks = new ArrayList<DocumentBlock>();
 
 		_size = 0;
@@ -178,7 +177,7 @@
 			_small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY);
 		}
 	}
-	public POIFSDocument(String name, InputStream stream) throws IOException {
+	public OPOIFSDocument(String name, InputStream stream) throws IOException {
 	   this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, stream);
 	}
 
@@ -190,7 +189,7 @@
 	 * @param path the path of the POIFSDocument
 	 * @param writer the writer who will eventually write the document contents
 	 */
-	public POIFSDocument(String name, int size, POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, POIFSWriterListener writer) {
+	public OPOIFSDocument(String name, int size, POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, POIFSWriterListener writer) {
 		_size = size;
 		_bigBigBlockSize = bigBlockSize;
 		_property = new DocumentProperty(name, _size);
@@ -203,14 +202,14 @@
 			_big_store = new BigBlockStore(_bigBigBlockSize, path, name, size, writer);
 		}
 	}
-	public POIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) {
+	public OPOIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) {
 	   this(name, size, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, path, writer);
 	}
 
 	/**
 	 * @return array of SmallDocumentBlocks; may be empty, cannot be null
 	 */
-	public BlockWritable[] getSmallBlocks() {
+	public SmallDocumentBlock[] getSmallBlocks() {
 		return _small_store.getBlocks();
 	}
 
diff --git a/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java
new file mode 100644
index 0000000..19abc48
--- /dev/null
+++ b/src/java/org/apache/poi/poifs/filesystem/OPOIFSFileSystem.java
@@ -0,0 +1,607 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+
+package org.apache.poi.poifs.filesystem;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.dev.POIFSViewable;
+import org.apache.poi.poifs.property.DirectoryProperty;
+import org.apache.poi.poifs.property.Property;
+import org.apache.poi.poifs.property.PropertyTable;
+import org.apache.poi.poifs.storage.BATBlock;
+import org.apache.poi.poifs.storage.BlockAllocationTableReader;
+import org.apache.poi.poifs.storage.BlockAllocationTableWriter;
+import org.apache.poi.poifs.storage.BlockList;
+import org.apache.poi.poifs.storage.BlockWritable;
+import org.apache.poi.poifs.storage.HeaderBlock;
+import org.apache.poi.poifs.storage.HeaderBlockConstants;
+import org.apache.poi.poifs.storage.HeaderBlockWriter;
+import org.apache.poi.poifs.storage.RawDataBlockList;
+import org.apache.poi.poifs.storage.SmallBlockTableReader;
+import org.apache.poi.poifs.storage.SmallBlockTableWriter;
+import org.apache.poi.util.CloseIgnoringInputStream;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LongField;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * <p>This is the main class of the POIFS system; it manages the entire
+ * life cycle of the filesystem.</p>
+ * <p>This is the older version, which uses more memory, and doesn't
+ *  support in-place writes.</p>
+ */
+public class OPOIFSFileSystem
+    implements POIFSViewable
+{
+	private static final POILogger _logger =
+		POILogFactory.getLogger(OPOIFSFileSystem.class);
+
+    /**
+     * Convenience method for clients that want to avoid the auto-close behaviour of the constructor.
+     */
+    public static InputStream createNonClosingInputStream(InputStream is) {
+        return new CloseIgnoringInputStream(is);
+    }
+
+    private PropertyTable _property_table;
+    private List<OPOIFSDocument> _documents;
+    private DirectoryNode _root;
+
+    /**
+     * What big block size the file uses. Most files
+     *  use 512 bytes, but a few use 4096
+     */
+    private POIFSBigBlockSize bigBlockSize = 
+       POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
+
+    /**
+     * Constructor, intended for writing
+     */
+    public OPOIFSFileSystem()
+    {
+        HeaderBlock header_block = new HeaderBlock(bigBlockSize);
+        _property_table = new PropertyTable(header_block);
+        _documents      = new ArrayList<OPOIFSDocument>();
+        _root           = null;
+    }
+
+    /**
+     * Create a OPOIFSFileSystem from an <tt>InputStream</tt>.  Normally the stream is read until
+     * EOF.  The stream is always closed.<p/>
+     *
+     * Some streams are usable after reaching EOF (typically those that return <code>true</code>
+     * for <tt>markSupported()</tt>).  In the unlikely case that the caller has such a stream
+     * <i>and</i> needs to use it after this constructor completes, a work around is to wrap the
+     * stream in order to trap the <tt>close()</tt> call.  A convenience method (
+     * <tt>createNonClosingInputStream()</tt>) has been provided for this purpose:
+     * <pre>
+     * InputStream wrappedStream = OPOIFSFileSystem.createNonClosingInputStream(is);
+     * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream);
+     * is.reset();
+     * doSomethingElse(is);
+     * </pre>
+     * Note also the special case of <tt>ByteArrayInputStream</tt> for which the <tt>close()</tt>
+     * method does nothing.
+     * <pre>
+     * ByteArrayInputStream bais = ...
+     * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() !
+     * bais.reset(); // no problem
+     * doSomethingElse(bais);
+     * </pre>
+     *
+     * @param stream the InputStream from which to read the data
+     *
+     * @exception IOException on errors reading, or on invalid data
+     */
+
+    public OPOIFSFileSystem(InputStream stream)
+        throws IOException
+    {
+        this();
+        boolean success = false;
+
+        HeaderBlock header_block;
+        RawDataBlockList data_blocks;
+        try {
+            // read the header block from the stream
+            header_block = new HeaderBlock(stream);
+            bigBlockSize = header_block.getBigBlockSize();
+
+            // read the rest of the stream into blocks
+            data_blocks = new RawDataBlockList(stream, bigBlockSize);
+            success = true;
+        } finally {
+            closeInputStream(stream, success);
+        }
+
+
+        // set up the block allocation table (necessary for the
+        // data_blocks to be manageable
+        new BlockAllocationTableReader(header_block.getBigBlockSize(),
+                                       header_block.getBATCount(),
+                                       header_block.getBATArray(),
+                                       header_block.getXBATCount(),
+                                       header_block.getXBATIndex(),
+                                       data_blocks);
+
+        // get property table from the document
+        PropertyTable properties =
+            new PropertyTable(header_block, data_blocks);
+
+        // init documents
+        processProperties(
+        		SmallBlockTableReader.getSmallDocumentBlocks(
+        		      bigBlockSize, data_blocks, properties.getRoot(),
+        				header_block.getSBATStart()
+        		),
+        		data_blocks,
+        		properties.getRoot().getChildren(),
+        		null,
+        		header_block.getPropertyStart()
+        );
+
+        // For whatever reason CLSID of root is always 0.
+        getRoot().setStorageClsid(properties.getRoot().getStorageClsid());
+    }
+    /**
+     * @param stream the stream to be closed
+     * @param success <code>false</code> if an exception is currently being thrown in the calling method
+     */
+    protected void closeInputStream(InputStream stream, boolean success) {
+
+        if(stream.markSupported() && !(stream instanceof ByteArrayInputStream)) {
+            String msg = "POIFS is closing the supplied input stream of type ("
+                    + stream.getClass().getName() + ") which supports mark/reset.  "
+                    + "This will be a problem for the caller if the stream will still be used.  "
+                    + "If that is the case the caller should wrap the input stream to avoid this close logic.  "
+                    + "This warning is only temporary and will not be present in future versions of POI.";
+            _logger.log(POILogger.WARN, msg);
+        }
+        try {
+            stream.close();
+        } catch (IOException e) {
+            if(success) {
+                throw new RuntimeException(e);
+            }
+            // else not success? Try block did not complete normally
+            // just print stack trace and leave original ex to be thrown
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Checks that the supplied InputStream (which MUST
+     *  support mark and reset, or be a PushbackInputStream)
+     *  has a POIFS (OLE2) header at the start of it.
+     * If your InputStream does not support mark / reset,
+     *  then wrap it in a PushBackInputStream, then be
+     *  sure to always use that, and not the original!
+     * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream
+     */
+    public static boolean hasPOIFSHeader(InputStream inp) throws IOException {
+        // We want to peek at the first 8 bytes
+        byte[] header = IOUtils.peekFirst8Bytes(inp);
+        return hasPOIFSHeader(header);
+    }
+    /**
+     * Checks if the supplied first 8 bytes of a stream / file
+     *  has a POIFS (OLE2) header.
+     */
+    public static boolean hasPOIFSHeader(byte[] header8Bytes) {
+        LongField signature = new LongField(HeaderBlockConstants._signature_offset, header8Bytes);
+
+        // Did it match the signature?
+        return (signature.get() == HeaderBlockConstants._signature);
+    }
+
+    /**
+     * Create a new document to be added to the root directory
+     *
+     * @param stream the InputStream from which the document's data
+     *               will be obtained
+     * @param name the name of the new POIFSDocument
+     *
+     * @return the new DocumentEntry
+     *
+     * @exception IOException on error creating the new POIFSDocument
+     */
+
+    public DocumentEntry createDocument(final InputStream stream,
+                                        final String name)
+        throws IOException
+    {
+        return getRoot().createDocument(name, stream);
+    }
+
+    /**
+     * create a new DocumentEntry in the root entry; the data will be
+     * provided later
+     *
+     * @param name the name of the new DocumentEntry
+     * @param size the size of the new DocumentEntry
+     * @param writer the writer of the new DocumentEntry
+     *
+     * @return the new DocumentEntry
+     *
+     * @exception IOException
+     */
+
+    public DocumentEntry createDocument(final String name, final int size,
+                                        final POIFSWriterListener writer)
+        throws IOException
+    {
+        return getRoot().createDocument(name, size, writer);
+    }
+
+    /**
+     * create a new DirectoryEntry in the root directory
+     *
+     * @param name the name of the new DirectoryEntry
+     *
+     * @return the new DirectoryEntry
+     *
+     * @exception IOException on name duplication
+     */
+
+    public DirectoryEntry createDirectory(final String name)
+        throws IOException
+    {
+        return getRoot().createDirectory(name);
+    }
+
+    /**
+     * Write the filesystem out
+     *
+     * @param stream the OutputStream to which the filesystem will be
+     *               written
+     *
+     * @exception IOException thrown on errors writing to the stream
+     */
+
+    public void writeFilesystem(final OutputStream stream)
+        throws IOException
+    {
+
+        // get the property table ready
+        _property_table.preWrite();
+
+        // create the small block store, and the SBAT
+        SmallBlockTableWriter      sbtw       =
+            new SmallBlockTableWriter(bigBlockSize, _documents, _property_table.getRoot());
+
+        // create the block allocation table
+        BlockAllocationTableWriter bat        =
+            new BlockAllocationTableWriter(bigBlockSize);
+
+        // create a list of BATManaged objects: the documents plus the
+        // property table and the small block table
+        List<Object> bm_objects = new ArrayList<Object>();
+
+        bm_objects.addAll(_documents);
+        bm_objects.add(_property_table);
+        bm_objects.add(sbtw);
+        bm_objects.add(sbtw.getSBAT());
+
+        // walk the list, allocating space for each and assigning each
+        // a starting block number
+        Iterator<Object> iter = bm_objects.iterator();
+
+        while (iter.hasNext())
+        {
+            BATManaged bmo         = ( BATManaged ) iter.next();
+            int        block_count = bmo.countBlocks();
+
+            if (block_count != 0)
+            {
+                bmo.setStartBlock(bat.allocateSpace(block_count));
+            }
+            else
+            {
+
+                // Either the BATManaged object is empty or its data
+                // is composed of SmallBlocks; in either case,
+                // allocating space in the BAT is inappropriate
+            }
+        }
+
+        // allocate space for the block allocation table and take its
+        // starting block
+        int               batStartBlock       = bat.createBlocks();
+
+        // get the extended block allocation table blocks
+        HeaderBlockWriter header_block_writer = new HeaderBlockWriter(bigBlockSize);
+        BATBlock[]        xbat_blocks         =
+            header_block_writer.setBATBlocks(bat.countBlocks(),
+                                             batStartBlock);
+
+        // set the property table start block
+        header_block_writer.setPropertyStart(_property_table.getStartBlock());
+
+        // set the small block allocation table start block
+        header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock());
+
+        // set the small block allocation table block count
+        header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount());
+
+        // the header is now properly initialized. Make a list of
+        // writers (the header block, followed by the documents, the
+        // property table, the small block store, the small block
+        // allocation table, the block allocation table, and the
+        // extended block allocation table blocks)
+        List<Object> writers = new ArrayList<Object>();
+
+        writers.add(header_block_writer);
+        writers.addAll(_documents);
+        writers.add(_property_table);
+        writers.add(sbtw);
+        writers.add(sbtw.getSBAT());
+        writers.add(bat);
+        for (int j = 0; j < xbat_blocks.length; j++)
+        {
+            writers.add(xbat_blocks[ j ]);
+        }
+
+        // now, write everything out
+        iter = writers.iterator();
+        while (iter.hasNext())
+        {
+            BlockWritable writer = ( BlockWritable ) iter.next();
+
+            writer.writeBlocks(stream);
+        }
+    }
+
+    /**
+     * read in a file and write it back out again
+     *
+     * @param args names of the files; arg[ 0 ] is the input file,
+     *             arg[ 1 ] is the output file
+     *
+     * @exception IOException
+     */
+
+    public static void main(String args[])
+        throws IOException
+    {
+        if (args.length != 2)
+        {
+            System.err.println(
+                "two arguments required: input filename and output filename");
+            System.exit(1);
+        }
+        FileInputStream  istream = new FileInputStream(args[ 0 ]);
+        FileOutputStream ostream = new FileOutputStream(args[ 1 ]);
+
+        new OPOIFSFileSystem(istream).writeFilesystem(ostream);
+        istream.close();
+        ostream.close();
+    }
+
+    /**
+     * get the root entry
+     *
+     * @return the root entry
+     */
+
+    public DirectoryNode getRoot()
+    {
+        if (_root == null)
+        {
+            _root = new DirectoryNode(_property_table.getRoot(), this, null);
+        }
+        return _root;
+    }
+
+    /**
+     * open a document in the root entry's list of entries
+     *
+     * @param documentName the name of the document to be opened
+     *
+     * @return a newly opened DocumentInputStream
+     *
+     * @exception IOException if the document does not exist or the
+     *            name is that of a DirectoryEntry
+     */
+
+    public DocumentInputStream createDocumentInputStream(
+            final String documentName)
+        throws IOException
+    {
+    	return getRoot().createDocumentInputStream(documentName);
+    }
+
+    /**
+     * add a new POIFSDocument
+     *
+     * @param document the POIFSDocument being added
+     */
+
+    void addDocument(final OPOIFSDocument document)
+    {
+        _documents.add(document);
+        _property_table.addProperty(document.getDocumentProperty());
+    }
+
+    /**
+     * add a new DirectoryProperty
+     *
+     * @param directory the DirectoryProperty being added
+     */
+
+    void addDirectory(final DirectoryProperty directory)
+    {
+        _property_table.addProperty(directory);
+    }
+
+    /**
+     * remove an entry
+     *
+     * @param entry to be removed
+     */
+
+    void remove(EntryNode entry)
+    {
+        _property_table.removeProperty(entry.getProperty());
+        if (entry.isDocumentEntry())
+        {
+            _documents.remove((( DocumentNode ) entry).getDocument());
+        }
+    }
+
+    private void processProperties(final BlockList small_blocks,
+                                   final BlockList big_blocks,
+                                   final Iterator<Property> properties,
+                                   final DirectoryNode dir,
+                                   final int headerPropertiesStartAt)
+        throws IOException
+    {
+        while (properties.hasNext())
+        {
+            Property      property = properties.next();
+            String        name     = property.getName();
+            DirectoryNode parent   = (dir == null)
+                                     ? (( DirectoryNode ) getRoot())
+                                     : dir;
+
+            if (property.isDirectory())
+            {
+                DirectoryNode new_dir =
+                    ( DirectoryNode ) parent.createDirectory(name);
+
+                new_dir.setStorageClsid( property.getStorageClsid() );
+
+                processProperties(
+                    small_blocks, big_blocks,
+                    (( DirectoryProperty ) property).getChildren(),
+                    new_dir, headerPropertiesStartAt);
+            }
+            else
+            {
+                int           startBlock = property.getStartBlock();
+                int           size       = property.getSize();
+                OPOIFSDocument document  = null;
+
+                if (property.shouldUseSmallBlocks())
+                {
+                    document =
+                        new OPOIFSDocument(name,
+                                           small_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
+                                           size);
+                }
+                else
+                {
+                    document =
+                        new OPOIFSDocument(name,
+                                           big_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
+                                           size);
+                }
+                parent.createDocument(document);
+            }
+        }
+    }
+
+    /* ********** START begin implementation of POIFSViewable ********** */
+
+    /**
+     * Get an array of objects, some of which may implement
+     * POIFSViewable
+     *
+     * @return an array of Object; may not be null, but may be empty
+     */
+
+    public Object [] getViewableArray()
+    {
+        if (preferArray())
+        {
+            return (( POIFSViewable ) getRoot()).getViewableArray();
+        }
+        return new Object[ 0 ];
+    }
+
+    /**
+     * Get an Iterator of objects, some of which may implement
+     * POIFSViewable
+     *
+     * @return an Iterator; may not be null, but may have an empty
+     * back end store
+     */
+
+    public Iterator<Object> getViewableIterator()
+    {
+        if (!preferArray())
+        {
+            return (( POIFSViewable ) getRoot()).getViewableIterator();
+        }
+        return Collections.emptyList().iterator();
+    }
+
+    /**
+     * Give viewers a hint as to whether to call getViewableArray or
+     * getViewableIterator
+     *
+     * @return true if a viewer should call getViewableArray, false if
+     *         a viewer should call getViewableIterator
+     */
+
+    public boolean preferArray()
+    {
+        return (( POIFSViewable ) getRoot()).preferArray();
+    }
+
+    /**
+     * Provides a short description of the object, to be used when a
+     * POIFSViewable object has not provided its contents.
+     *
+     * @return short description
+     */
+
+    public String getShortDescription()
+    {
+        return "POIFS FileSystem";
+    }
+
+    /**
+     * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
+     */
+    public int getBigBlockSize() {
+    	return bigBlockSize.getBigBlockSize();
+    }
+    /**
+     * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
+     */
+    public POIFSBigBlockSize getBigBlockSizeDetails() {
+      return bigBlockSize;
+    }
+
+    /* **********  END  begin implementation of POIFSViewable ********** */
+}   // end public class OPOIFSFileSystem
+
diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
index 7169d91..5afb4eb 100644
--- a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
+++ b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
@@ -19,44 +19,22 @@
 
 package org.apache.poi.poifs.filesystem;
 
-import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
 
-import org.apache.poi.poifs.common.POIFSBigBlockSize;
-import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
-import org.apache.poi.poifs.property.DirectoryProperty;
-import org.apache.poi.poifs.property.Property;
-import org.apache.poi.poifs.property.PropertyTable;
-import org.apache.poi.poifs.storage.*;
 import org.apache.poi.util.CloseIgnoringInputStream;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.LongField;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
 
 /**
- * This is the main class of the POIFS system; it manages the entire
- * life cycle of the filesystem.
- *
- * @author Marc Johnson (mjohnson at apache dot org)
+ * Transition class for the move from {@link POIFSFileSystem} to 
+ *  {@link OPOIFSFileSystem}, and from {@link NPOIFSFileSystem} to
+ *  {@link POIFSFileSystem}. Currently, this is OPOIFS-powered
  */
 
 public class POIFSFileSystem
+    extends NPOIFSFileSystem // TODO Temporary workaround during #56791
     implements POIFSViewable
 {
-	private static final POILogger _logger =
-		POILogFactory.getLogger(POIFSFileSystem.class);
-
     /**
      * Convenience method for clients that want to avoid the auto-close behaviour of the constructor.
      */
@@ -64,26 +42,12 @@
         return new CloseIgnoringInputStream(is);
     }
 
-    private PropertyTable _property_table;
-    private List<POIFSViewable>          _documents;
-    private DirectoryNode _root;
-
-    /**
-     * What big block size the file uses. Most files
-     *  use 512 bytes, but a few use 4096
-     */
-    private POIFSBigBlockSize bigBlockSize = 
-       POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
-
     /**
      * Constructor, intended for writing
      */
     public POIFSFileSystem()
     {
-        HeaderBlock header_block = new HeaderBlock(bigBlockSize);
-        _property_table = new PropertyTable(header_block);
-        _documents      = new ArrayList<POIFSViewable>();
-        _root           = null;
+        super();
     }
 
     /**
@@ -118,76 +82,7 @@
     public POIFSFileSystem(InputStream stream)
         throws IOException
     {
-        this();
-        boolean success = false;
-
-        HeaderBlock header_block;
-        RawDataBlockList data_blocks;
-        try {
-            // read the header block from the stream
-            header_block = new HeaderBlock(stream);
-            bigBlockSize = header_block.getBigBlockSize();
-
-            // read the rest of the stream into blocks
-            data_blocks = new RawDataBlockList(stream, bigBlockSize);
-            success = true;
-        } finally {
-            closeInputStream(stream, success);
-        }
-
-
-        // set up the block allocation table (necessary for the
-        // data_blocks to be manageable
-        new BlockAllocationTableReader(header_block.getBigBlockSize(),
-                                       header_block.getBATCount(),
-                                       header_block.getBATArray(),
-                                       header_block.getXBATCount(),
-                                       header_block.getXBATIndex(),
-                                       data_blocks);
-
-        // get property table from the document
-        PropertyTable properties =
-            new PropertyTable(header_block, data_blocks);
-
-        // init documents
-        processProperties(
-        		SmallBlockTableReader.getSmallDocumentBlocks(
-        		      bigBlockSize, data_blocks, properties.getRoot(),
-        				header_block.getSBATStart()
-        		),
-        		data_blocks,
-        		properties.getRoot().getChildren(),
-        		null,
-        		header_block.getPropertyStart()
-        );
-
-        // For whatever reason CLSID of root is always 0.
-        getRoot().setStorageClsid(properties.getRoot().getStorageClsid());
-    }
-    /**
-     * @param stream the stream to be closed
-     * @param success <code>false</code> if an exception is currently being thrown in the calling method
-     */
-    private void closeInputStream(InputStream stream, boolean success) {
-
-        if(stream.markSupported() && !(stream instanceof ByteArrayInputStream)) {
-            String msg = "POIFS is closing the supplied input stream of type ("
-                    + stream.getClass().getName() + ") which supports mark/reset.  "
-                    + "This will be a problem for the caller if the stream will still be used.  "
-                    + "If that is the case the caller should wrap the input stream to avoid this close logic.  "
-                    + "This warning is only temporary and will not be present in future versions of POI.";
-            _logger.log(POILogger.WARN, msg);
-        }
-        try {
-            stream.close();
-        } catch (IOException e) {
-            if(success) {
-                throw new RuntimeException(e);
-            }
-            // else not success? Try block did not complete normally
-            // just print stack trace and leave original ex to be thrown
-            e.printStackTrace();
-        }
+        super(stream);
     }
 
     /**
@@ -200,180 +95,14 @@
      * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream
      */
     public static boolean hasPOIFSHeader(InputStream inp) throws IOException {
-        // We want to peek at the first 8 bytes
-        inp.mark(8);
-
-        byte[] header = new byte[8];
-        IOUtils.readFully(inp, header);
-        LongField signature = new LongField(HeaderBlockConstants._signature_offset, header);
-
-        // Wind back those 8 bytes
-        if(inp instanceof PushbackInputStream) {
-            PushbackInputStream pin = (PushbackInputStream)inp;
-            pin.unread(header);
-        } else {
-            inp.reset();
-        }
-
-        // Did it match the signature?
-        return (signature.get() == HeaderBlockConstants._signature);
+        return NPOIFSFileSystem.hasPOIFSHeader(inp);
     }
-
     /**
-     * Create a new document to be added to the root directory
-     *
-     * @param stream the InputStream from which the document's data
-     *               will be obtained
-     * @param name the name of the new POIFSDocument
-     *
-     * @return the new DocumentEntry
-     *
-     * @exception IOException on error creating the new POIFSDocument
+     * Checks if the supplied first 8 bytes of a stream / file
+     *  has a POIFS (OLE2) header.
      */
-
-    public DocumentEntry createDocument(final InputStream stream,
-                                        final String name)
-        throws IOException
-    {
-        return getRoot().createDocument(name, stream);
-    }
-
-    /**
-     * create a new DocumentEntry in the root entry; the data will be
-     * provided later
-     *
-     * @param name the name of the new DocumentEntry
-     * @param size the size of the new DocumentEntry
-     * @param writer the writer of the new DocumentEntry
-     *
-     * @return the new DocumentEntry
-     *
-     * @exception IOException
-     */
-
-    public DocumentEntry createDocument(final String name, final int size,
-                                        final POIFSWriterListener writer)
-        throws IOException
-    {
-        return getRoot().createDocument(name, size, writer);
-    }
-
-    /**
-     * create a new DirectoryEntry in the root directory
-     *
-     * @param name the name of the new DirectoryEntry
-     *
-     * @return the new DirectoryEntry
-     *
-     * @exception IOException on name duplication
-     */
-
-    public DirectoryEntry createDirectory(final String name)
-        throws IOException
-    {
-        return getRoot().createDirectory(name);
-    }
-
-    /**
-     * Write the filesystem out
-     *
-     * @param stream the OutputStream to which the filesystem will be
-     *               written
-     *
-     * @exception IOException thrown on errors writing to the stream
-     */
-
-    public void writeFilesystem(final OutputStream stream)
-        throws IOException
-    {
-
-        // get the property table ready
-        _property_table.preWrite();
-
-        // create the small block store, and the SBAT
-        SmallBlockTableWriter      sbtw       =
-            new SmallBlockTableWriter(bigBlockSize, _documents, _property_table.getRoot());
-
-        // create the block allocation table
-        BlockAllocationTableWriter bat        =
-            new BlockAllocationTableWriter(bigBlockSize);
-
-        // create a list of BATManaged objects: the documents plus the
-        // property table and the small block table
-        List<Object> bm_objects = new ArrayList<Object>();
-
-        bm_objects.addAll(_documents);
-        bm_objects.add(_property_table);
-        bm_objects.add(sbtw);
-        bm_objects.add(sbtw.getSBAT());
-
-        // walk the list, allocating space for each and assigning each
-        // a starting block number
-        Iterator<Object> iter = bm_objects.iterator();
-
-        while (iter.hasNext())
-        {
-            BATManaged bmo         = ( BATManaged ) iter.next();
-            int        block_count = bmo.countBlocks();
-
-            if (block_count != 0)
-            {
-                bmo.setStartBlock(bat.allocateSpace(block_count));
-            }
-            else
-            {
-
-                // Either the BATManaged object is empty or its data
-                // is composed of SmallBlocks; in either case,
-                // allocating space in the BAT is inappropriate
-            }
-        }
-
-        // allocate space for the block allocation table and take its
-        // starting block
-        int               batStartBlock       = bat.createBlocks();
-
-        // get the extended block allocation table blocks
-        HeaderBlockWriter header_block_writer = new HeaderBlockWriter(bigBlockSize);
-        BATBlock[]        xbat_blocks         =
-            header_block_writer.setBATBlocks(bat.countBlocks(),
-                                             batStartBlock);
-
-        // set the property table start block
-        header_block_writer.setPropertyStart(_property_table.getStartBlock());
-
-        // set the small block allocation table start block
-        header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock());
-
-        // set the small block allocation table block count
-        header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount());
-
-        // the header is now properly initialized. Make a list of
-        // writers (the header block, followed by the documents, the
-        // property table, the small block store, the small block
-        // allocation table, the block allocation table, and the
-        // extended block allocation table blocks)
-        List<Object> writers = new ArrayList<Object>();
-
-        writers.add(header_block_writer);
-        writers.addAll(_documents);
-        writers.add(_property_table);
-        writers.add(sbtw);
-        writers.add(sbtw.getSBAT());
-        writers.add(bat);
-        for (int j = 0; j < xbat_blocks.length; j++)
-        {
-            writers.add(xbat_blocks[ j ]);
-        }
-
-        // now, write everything out
-        iter = writers.iterator();
-        while (iter.hasNext())
-        {
-            BlockWritable writer = ( BlockWritable ) iter.next();
-
-            writer.writeBlocks(stream);
-        }
+    public static boolean hasPOIFSHeader(byte[] header8Bytes) {
+        return NPOIFSFileSystem.hasPOIFSHeader(header8Bytes);
     }
 
     /**
@@ -388,216 +117,7 @@
     public static void main(String args[])
         throws IOException
     {
-        if (args.length != 2)
-        {
-            System.err.println(
-                "two arguments required: input filename and output filename");
-            System.exit(1);
-        }
-        FileInputStream  istream = new FileInputStream(args[ 0 ]);
-        FileOutputStream ostream = new FileOutputStream(args[ 1 ]);
-
-        new POIFSFileSystem(istream).writeFilesystem(ostream);
-        istream.close();
-        ostream.close();
+        OPOIFSFileSystem.main(args);
     }
-
-    /**
-     * get the root entry
-     *
-     * @return the root entry
-     */
-
-    public DirectoryNode getRoot()
-    {
-        if (_root == null)
-        {
-            _root = new DirectoryNode(_property_table.getRoot(), this, null);
-        }
-        return _root;
-    }
-
-    /**
-     * open a document in the root entry's list of entries
-     *
-     * @param documentName the name of the document to be opened
-     *
-     * @return a newly opened DocumentInputStream
-     *
-     * @exception IOException if the document does not exist or the
-     *            name is that of a DirectoryEntry
-     */
-
-    public DocumentInputStream createDocumentInputStream(
-            final String documentName)
-        throws IOException
-    {
-    	return getRoot().createDocumentInputStream(documentName);
-    }
-
-    /**
-     * add a new POIFSDocument
-     *
-     * @param document the POIFSDocument being added
-     */
-
-    void addDocument(final POIFSDocument document)
-    {
-        _documents.add(document);
-        _property_table.addProperty(document.getDocumentProperty());
-    }
-
-    /**
-     * add a new DirectoryProperty
-     *
-     * @param directory the DirectoryProperty being added
-     */
-
-    void addDirectory(final DirectoryProperty directory)
-    {
-        _property_table.addProperty(directory);
-    }
-
-    /**
-     * remove an entry
-     *
-     * @param entry to be removed
-     */
-
-    void remove(EntryNode entry)
-    {
-        _property_table.removeProperty(entry.getProperty());
-        if (entry.isDocumentEntry())
-        {
-            _documents.remove((( DocumentNode ) entry).getDocument());
-        }
-    }
-
-    private void processProperties(final BlockList small_blocks,
-                                   final BlockList big_blocks,
-                                   final Iterator<Property> properties,
-                                   final DirectoryNode dir,
-                                   final int headerPropertiesStartAt)
-        throws IOException
-    {
-        while (properties.hasNext())
-        {
-            Property      property = properties.next();
-            String        name     = property.getName();
-            DirectoryNode parent   = (dir == null)
-                                     ? (( DirectoryNode ) getRoot())
-                                     : dir;
-
-            if (property.isDirectory())
-            {
-                DirectoryNode new_dir =
-                    ( DirectoryNode ) parent.createDirectory(name);
-
-                new_dir.setStorageClsid( property.getStorageClsid() );
-
-                processProperties(
-                    small_blocks, big_blocks,
-                    (( DirectoryProperty ) property).getChildren(),
-                    new_dir, headerPropertiesStartAt);
-            }
-            else
-            {
-                int           startBlock = property.getStartBlock();
-                int           size       = property.getSize();
-                POIFSDocument document   = null;
-
-                if (property.shouldUseSmallBlocks())
-                {
-                    document =
-                        new POIFSDocument(name,
-                                          small_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
-                                          size);
-                }
-                else
-                {
-                    document =
-                        new POIFSDocument(name,
-                                          big_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
-                                          size);
-                }
-                parent.createDocument(document);
-            }
-        }
-    }
-
-    /* ********** START begin implementation of POIFSViewable ********** */
-
-    /**
-     * Get an array of objects, some of which may implement
-     * POIFSViewable
-     *
-     * @return an array of Object; may not be null, but may be empty
-     */
-
-    public Object [] getViewableArray()
-    {
-        if (preferArray())
-        {
-            return (( POIFSViewable ) getRoot()).getViewableArray();
-        }
-        return new Object[ 0 ];
-    }
-
-    /**
-     * Get an Iterator of objects, some of which may implement
-     * POIFSViewable
-     *
-     * @return an Iterator; may not be null, but may have an empty
-     * back end store
-     */
-
-    public Iterator<Object> getViewableIterator()
-    {
-        if (!preferArray())
-        {
-            return (( POIFSViewable ) getRoot()).getViewableIterator();
-        }
-        return Collections.emptyList().iterator();
-    }
-
-    /**
-     * Give viewers a hint as to whether to call getViewableArray or
-     * getViewableIterator
-     *
-     * @return true if a viewer should call getViewableArray, false if
-     *         a viewer should call getViewableIterator
-     */
-
-    public boolean preferArray()
-    {
-        return (( POIFSViewable ) getRoot()).preferArray();
-    }
-
-    /**
-     * Provides a short description of the object, to be used when a
-     * POIFSViewable object has not provided its contents.
-     *
-     * @return short description
-     */
-
-    public String getShortDescription()
-    {
-        return "POIFS FileSystem";
-    }
-
-    /**
-     * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
-     */
-    public int getBigBlockSize() {
-    	return bigBlockSize.getBigBlockSize();
-    }
-    /**
-     * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
-     */
-    public POIFSBigBlockSize getBigBlockSizeDetails() {
-      return bigBlockSize;
-    }
-
-    /* **********  END  begin implementation of POIFSViewable ********** */
-}   // end public class POIFSFileSystem
+}
 
diff --git a/src/java/org/apache/poi/poifs/property/DirectoryProperty.java b/src/java/org/apache/poi/poifs/property/DirectoryProperty.java
index a73221a..d86e73a 100644
--- a/src/java/org/apache/poi/poifs/property/DirectoryProperty.java
+++ b/src/java/org/apache/poi/poifs/property/DirectoryProperty.java
@@ -28,10 +28,8 @@
 
 /**
  * Directory property
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
-public class DirectoryProperty extends Property implements Parent { // TODO - fix instantiable superclass
+public class DirectoryProperty extends Property implements Parent, Iterable<Property> { // TODO - fix instantiable superclass
 
     /** List of Property instances */
     private List<Property> _children;
@@ -241,6 +239,13 @@
     {
         return _children.iterator();
     }
+    /**
+     * Get an iterator over the children of this Parent, alias for
+     *  {@link #getChildren()} which supports foreach use
+     */
+    public Iterator<Property> iterator() {
+        return getChildren();
+    }
 
     /**
      * Add a new child to the collection of children
diff --git a/src/java/org/apache/poi/poifs/property/DocumentProperty.java b/src/java/org/apache/poi/poifs/property/DocumentProperty.java
index 67c8b03..3ba3c08 100644
--- a/src/java/org/apache/poi/poifs/property/DocumentProperty.java
+++ b/src/java/org/apache/poi/poifs/property/DocumentProperty.java
@@ -19,12 +19,10 @@
 
 package org.apache.poi.poifs.property;
 
-import org.apache.poi.poifs.filesystem.POIFSDocument;
+import org.apache.poi.poifs.filesystem.OPOIFSDocument;
 
 /**
  * Trivial extension of Property for POIFSDocuments
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
 
 public class DocumentProperty
@@ -32,7 +30,7 @@
 {
 
     // the POIFSDocument this property is associated with
-    private POIFSDocument _document;
+    private OPOIFSDocument _document;
 
     /**
      * Constructor
@@ -72,7 +70,7 @@
      * @param doc the associated POIFSDocument
      */
 
-    public void setDocument(POIFSDocument doc)
+    public void setDocument(OPOIFSDocument doc)
     {
         _document = doc;
     }
@@ -83,7 +81,7 @@
      * @return the associated document
      */
 
-    public POIFSDocument getDocument()
+    public OPOIFSDocument getDocument()
     {
         return _document;
     }
diff --git a/src/java/org/apache/poi/poifs/property/PropertyTable.java b/src/java/org/apache/poi/poifs/property/PropertyTable.java
index 45a9734..75ca4a0 100644
--- a/src/java/org/apache/poi/poifs/property/PropertyTable.java
+++ b/src/java/org/apache/poi/poifs/property/PropertyTable.java
@@ -21,14 +21,13 @@
 import java.io.OutputStream;
 
 import org.apache.poi.poifs.common.POIFSBigBlockSize;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.poifs.storage.BlockWritable;
 import org.apache.poi.poifs.storage.HeaderBlock;
 import org.apache.poi.poifs.storage.PropertyBlock;
 import org.apache.poi.poifs.storage.RawDataBlockList;
 
 /**
- * This class embodies the Property Table for the {@link POIFSFileSystem}; 
+ * This class embodies the Property Table for the {@link org.apache.poi.poifs.filesystem.POIFSFileSystem}; 
  *  this is basically the directory for all of the documents in the
  * filesystem.
  *
diff --git a/src/java/org/apache/poi/poifs/property/PropertyTableBase.java b/src/java/org/apache/poi/poifs/property/PropertyTableBase.java
index b3690c5..477cf03 100644
--- a/src/java/org/apache/poi/poifs/property/PropertyTableBase.java
+++ b/src/java/org/apache/poi/poifs/property/PropertyTableBase.java
@@ -111,6 +111,11 @@
         while (!children.empty())
         {
             Property property = children.pop();
+            if (property == null)
+            {
+                // unknown / unsupported / corrupted property, skip
+                continue;
+            }
 
             root.addChild(property);
             if (property.isDirectory())
diff --git a/src/java/org/apache/poi/poifs/property/RootProperty.java b/src/java/org/apache/poi/poifs/property/RootProperty.java
index b934a26..5a8f3d5 100644
--- a/src/java/org/apache/poi/poifs/property/RootProperty.java
+++ b/src/java/org/apache/poi/poifs/property/RootProperty.java
@@ -22,8 +22,6 @@
 
 /**
  * Root property
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
 public final class RootProperty extends DirectoryProperty {
    private static final String NAME = "Root Entry";
diff --git a/src/java/org/apache/poi/poifs/storage/BATBlock.java b/src/java/org/apache/poi/poifs/storage/BATBlock.java
index 8712e65..5309964 100644
--- a/src/java/org/apache/poi/poifs/storage/BATBlock.java
+++ b/src/java/org/apache/poi/poifs/storage/BATBlock.java
@@ -30,8 +30,6 @@
 /**
  * A block of block allocation table entries. BATBlocks are created
  * only through a static factory method: createBATBlocks.
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
 public final class BATBlock extends BigBlock {
     /**
@@ -301,6 +299,21 @@
     public boolean hasFreeSectors() {
        return _has_free_sectors;
     }
+    /**
+     * How many sectors in this block are taken?
+     * Note that calling {@link #hasFreeSectors()} is much quicker
+     */
+    public int getUsedSectors(boolean isAnXBAT) {
+        int usedSectors = 0;
+        int toCheck = _values.length;
+        if (isAnXBAT) toCheck--; // Last is a chain location
+        for(int k=0; k<toCheck; k++) {
+            if(_values[k] != POIFSConstants.UNUSED_BLOCK) {
+                usedSectors ++;
+            }
+        }
+        return usedSectors;
+    }
     
     public int getValueAt(int relativeOffset) {
        if(relativeOffset >= _values.length) {
diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
index 8b6efd3..2f95283 100644
--- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
+++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
@@ -25,13 +25,66 @@
 /**
  * This class implements reading the small document block list from an
  * existing file
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
 public final class SmallBlockTableReader {
+    private static BlockList prepareSmallDocumentBlocks(
+            final POIFSBigBlockSize bigBlockSize,
+            final RawDataBlockList blockList, final RootProperty root,
+            final int sbatStart)
+        throws IOException
+    {
+        // Fetch the blocks which hold the Small Blocks stream
+        ListManagedBlock [] smallBlockBlocks = 
+                blockList.fetchBlocks(root.getStartBlock(), -1);
+        
+       // Turn that into a list
+        BlockList list =new SmallDocumentBlockList(
+                SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks));
+
+        return list;
+    }
+    private static BlockAllocationTableReader prepareReader(
+            final POIFSBigBlockSize bigBlockSize,
+            final RawDataBlockList blockList, final BlockList list, 
+            final RootProperty root, final int sbatStart)
+        throws IOException
+    {
+        // Process the SBAT and blocks
+        return new BlockAllocationTableReader(bigBlockSize,
+                blockList.fetchBlocks(sbatStart, -1),
+                list);
+    }
+            
+    /**
+     * Fetch the small document block reader from an existing file, normally
+     *  needed for debugging and low level dumping. You should typically call
+     *  {@link #getSmallDocumentBlocks(POIFSBigBlockSize, RawDataBlockList, RootProperty, int)}
+     *  instead.
+     *
+     * @param blockList the raw data from which the small block table
+     *                  will be extracted
+     * @param root the root property (which contains the start block
+     *             and small block table size)
+     * @param sbatStart the start block of the SBAT
+     *
+     * @return the small document block reader
+     *
+     * @exception IOException
+     */
+    public static BlockAllocationTableReader _getSmallDocumentBlockReader(
+            final POIFSBigBlockSize bigBlockSize,
+            final RawDataBlockList blockList, final RootProperty root,
+            final int sbatStart)
+        throws IOException
+    {
+       BlockList list = prepareSmallDocumentBlocks(
+                bigBlockSize, blockList, root, sbatStart);
+        return prepareReader(
+                bigBlockSize, blockList, list, root, sbatStart);
+    }
 
     /**
-     * fetch the small document block list from an existing file
+     * Fetch the small document block list from an existing file
      *
      * @param blockList the raw data from which the small block table
      *                  will be extracted
@@ -49,18 +102,9 @@
             final int sbatStart)
         throws IOException
     {
-       // Fetch the blocks which hold the Small Blocks stream
-       ListManagedBlock [] smallBlockBlocks = 
-          blockList.fetchBlocks(root.getStartBlock(), -1);
-        
-       // Turn that into a list
-       BlockList list =new SmallDocumentBlockList(
-             SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks));
-
-       // Process
-        new BlockAllocationTableReader(bigBlockSize,
-                                       blockList.fetchBlocks(sbatStart, -1),
-                                       list);
+        BlockList list = prepareSmallDocumentBlocks(
+                bigBlockSize, blockList, root, sbatStart);
+        prepareReader(bigBlockSize, blockList, list, root, sbatStart);
         return list;
     }
 }
diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java
index 2db7bf4..9c98bb4 100644
--- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java
+++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java
@@ -22,7 +22,7 @@
 import org.apache.poi.poifs.common.POIFSBigBlockSize;
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.filesystem.BATManaged;
-import org.apache.poi.poifs.filesystem.POIFSDocument;
+import org.apache.poi.poifs.filesystem.OPOIFSDocument;
 import org.apache.poi.poifs.property.RootProperty;
 
 import java.util.*;
@@ -40,7 +40,7 @@
     implements BlockWritable, BATManaged
 {
     private BlockAllocationTableWriter _sbat;
-    private List                       _small_blocks;
+    private List<SmallDocumentBlock>   _small_blocks;
     private int                        _big_block_count;
     private RootProperty               _root;
 
@@ -50,20 +50,17 @@
      * @param documents a List of POIFSDocument instances
      * @param root the Filesystem's root property
      */
-
     public SmallBlockTableWriter(final POIFSBigBlockSize bigBlockSize,
-                                 final List documents,
+                                 final List<OPOIFSDocument> documents,
                                  final RootProperty root)
     {
         _sbat         = new BlockAllocationTableWriter(bigBlockSize);
-        _small_blocks = new ArrayList();
+        _small_blocks = new ArrayList<SmallDocumentBlock>();
         _root         = root;
-        Iterator iter = documents.iterator();
 
-        while (iter.hasNext())
+        for (OPOIFSDocument doc : documents)
         {
-            POIFSDocument   doc    = ( POIFSDocument ) iter.next();
-            BlockWritable[] blocks = doc.getSmallBlocks();
+            SmallDocumentBlock[] blocks = doc.getSmallBlocks();
 
             if (blocks.length != 0)
             {
@@ -143,11 +140,8 @@
     public void writeBlocks(final OutputStream stream)
         throws IOException
     {
-        Iterator iter = _small_blocks.iterator();
-
-        while (iter.hasNext())
-        {
-            (( BlockWritable ) iter.next()).writeBlocks(stream);
+        for (BlockWritable block : _small_blocks) {
+            block.writeBlocks(stream);
         }
     }
 
diff --git a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
index 8c726ca..d09bf9e 100644
--- a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
+++ b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
@@ -29,8 +29,6 @@
 /**
  * Storage for documents that are too small to use regular
  * DocumentBlocks for their data
- *
- * @author  Marc Johnson (mjohnson at apache dot org)
  */
 public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock {
     private static final int BLOCK_SHIFT = 6;
@@ -49,7 +47,7 @@
         System.arraycopy(data, index * _block_size, _data, 0, _block_size);
     }
 
-    private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize)
+    protected SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize)
     {
         _bigBlockSize = bigBlockSize;
         _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize);
@@ -110,7 +108,7 @@
      *
      * @return number of big blocks the list encompasses
      */
-    public static int fill(POIFSBigBlockSize bigBlockSize, List blocks)
+    public static int fill(POIFSBigBlockSize bigBlockSize, List<SmallDocumentBlock> blocks)
     {
         int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize);
         
@@ -168,12 +166,12 @@
      *
      * @return a List of SmallDocumentBlock's extracted from the input
      */
-    public static List extract(POIFSBigBlockSize bigBlockSize, ListManagedBlock [] blocks)
+    public static List<SmallDocumentBlock> extract(POIFSBigBlockSize bigBlockSize, ListManagedBlock [] blocks)
         throws IOException
     {
         int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize);
         
-        List sdbs = new ArrayList();
+        List<SmallDocumentBlock> sdbs = new ArrayList<SmallDocumentBlock>();
 
         for (int j = 0; j < blocks.length; j++)
         {
@@ -204,6 +202,11 @@
     {
         return size * _block_size;
     }
+    
+    protected int getSmallBlocksPerBigBlock()
+    {
+        return _blocks_per_big_block;
+    }
 
     private static SmallDocumentBlock makeEmptySmallDocumentBlock(POIFSBigBlockSize bigBlockSize)
     {
diff --git a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
index a510f8e..cc6bb7c 100644
--- a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
+++ b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
@@ -23,24 +23,19 @@
 
 /**
  * A list of SmallDocumentBlocks instances, and methods to manage the list
- *
- * @author Marc Johnson (mjohnson at apache dot org)
  */
-
 public class SmallDocumentBlockList
     extends BlockListImpl
 {
-
     /**
      * Constructor SmallDocumentBlockList
      *
      * @param blocks a list of SmallDocumentBlock instances
      */
 
-    public SmallDocumentBlockList(final List blocks)
+    public SmallDocumentBlockList(final List<SmallDocumentBlock> blocks)
     {
-        setBlocks(( SmallDocumentBlock [] ) blocks
-            .toArray(new SmallDocumentBlock[ blocks.size() ]));
+        setBlocks(blocks.toArray(new SmallDocumentBlock[blocks.size()]));
     }
-}   // end public class SmallDocumentBlockList
+}
 
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java b/src/java/org/apache/poi/sl/draw/DrawAutoShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java
rename to src/java/org/apache/poi/sl/draw/DrawAutoShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawBackground.java b/src/java/org/apache/poi/sl/draw/DrawBackground.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawBackground.java
rename to src/java/org/apache/poi/sl/draw/DrawBackground.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawConnectorShape.java b/src/java/org/apache/poi/sl/draw/DrawConnectorShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawConnectorShape.java
rename to src/java/org/apache/poi/sl/draw/DrawConnectorShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java b/src/java/org/apache/poi/sl/draw/DrawFactory.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java
rename to src/java/org/apache/poi/sl/draw/DrawFactory.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFontManager.java b/src/java/org/apache/poi/sl/draw/DrawFontManager.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawFontManager.java
rename to src/java/org/apache/poi/sl/draw/DrawFontManager.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java b/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java
rename to src/java/org/apache/poi/sl/draw/DrawFreeformShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawGroupShape.java b/src/java/org/apache/poi/sl/draw/DrawGroupShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawGroupShape.java
rename to src/java/org/apache/poi/sl/draw/DrawGroupShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java b/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java
rename to src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java
rename to src/java/org/apache/poi/sl/draw/DrawPaint.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawPictureShape.java b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawPictureShape.java
rename to src/java/org/apache/poi/sl/draw/DrawPictureShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java b/src/java/org/apache/poi/sl/draw/DrawShape.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java
rename to src/java/org/apache/poi/sl/draw/DrawShape.java
index c2c9b5f..13ef429 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawShape.java
@@ -21,7 +21,6 @@
 import java.awt.geom.AffineTransform;

 import java.awt.geom.Rectangle2D;

 

-import org.apache.poi.hslf.usermodel.HSLFShape;

 import org.apache.poi.sl.usermodel.PlaceableShape;

 import org.apache.poi.sl.usermodel.Shape;

 

@@ -73,7 +72,7 @@
                 // and later on, turn it around again to compare it with its original size ...

 

                 AffineTransform txs;

-                if (ps instanceof HSLFShape) {

+                if (ps.getClass().getCanonicalName().toLowerCase().contains("hslf")) {

                     txs = new AffineTransform(tx);

                 } else {

                     // this handling is only based on try and error ... not sure why xslf is handled differently.

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java b/src/java/org/apache/poi/sl/draw/DrawSheet.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java
rename to src/java/org/apache/poi/sl/draw/DrawSheet.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java
rename to src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java b/src/java/org/apache/poi/sl/draw/DrawSlide.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java
rename to src/java/org/apache/poi/sl/draw/DrawSlide.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTableShape.java b/src/java/org/apache/poi/sl/draw/DrawTableShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawTableShape.java
rename to src/java/org/apache/poi/sl/draw/DrawTableShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java b/src/java/org/apache/poi/sl/draw/DrawTextBox.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java
rename to src/java/org/apache/poi/sl/draw/DrawTextBox.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextFragment.java b/src/java/org/apache/poi/sl/draw/DrawTextFragment.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawTextFragment.java
rename to src/java/org/apache/poi/sl/draw/DrawTextFragment.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java
rename to src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java
rename to src/java/org/apache/poi/sl/draw/DrawTextShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/Drawable.java b/src/java/org/apache/poi/sl/draw/Drawable.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/Drawable.java
rename to src/java/org/apache/poi/sl/draw/Drawable.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java b/src/java/org/apache/poi/sl/draw/ImageRenderer.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java
rename to src/java/org/apache/poi/sl/draw/ImageRenderer.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/PathGradientPaint.java b/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/PathGradientPaint.java
rename to src/java/org/apache/poi/sl/draw/PathGradientPaint.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java b/src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java
index 32ee2a0..d7fc0ae 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTAdjPoint2D.java
@@ -45,9 +45,9 @@
 @XmlType(name = "CT_AdjPoint2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTAdjPoint2D {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "x", required = true)

     protected String x;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "y", required = true)

     protected String y;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java b/src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java
similarity index 99%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java
rename to src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java
index c5ef786..d684ccc 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTAdjustHandleList.java
@@ -53,8 +53,8 @@
 public class CTAdjustHandleList {

 

     @XmlElements({

-        @XmlElement(name = "ahPolar", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPolarAdjustHandle.class),

-        @XmlElement(name = "ahXY", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTXYAdjustHandle.class)

+        @XmlElement(name = "ahXY", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTXYAdjustHandle.class),

+        @XmlElement(name = "ahPolar", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPolarAdjustHandle.class)

     })

     protected List<Object> ahXYOrAhPolar;

 

@@ -76,8 +76,8 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

-     * {@link CTPolarAdjustHandle }

      * {@link CTXYAdjustHandle }

+     * {@link CTPolarAdjustHandle }

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAngle.java b/src/java/org/apache/poi/sl/draw/binding/CTAngle.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAngle.java
rename to src/java/org/apache/poi/sl/draw/binding/CTAngle.java
index 2e39602..2da2373 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTAngle.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTAngle.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_Angle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTAngle {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTColor.java b/src/java/org/apache/poi/sl/draw/binding/CTColor.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTColor.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTColorMRU.java b/src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java
similarity index 99%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTColorMRU.java
rename to src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java
index fb3e2cc..8ec68ba 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTColorMRU.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTColorMRU.java
@@ -52,12 +52,12 @@
 public class CTColorMRU {

 

     @XmlElements({

-        @XmlElement(name = "hslClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTHslColor.class),

-        @XmlElement(name = "srgbClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSRgbColor.class),

-        @XmlElement(name = "schemeClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSchemeColor.class),

         @XmlElement(name = "scrgbClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTScRgbColor.class),

-        @XmlElement(name = "prstClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPresetColor.class),

-        @XmlElement(name = "sysClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSystemColor.class)

+        @XmlElement(name = "srgbClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSRgbColor.class),

+        @XmlElement(name = "hslClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTHslColor.class),

+        @XmlElement(name = "sysClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSystemColor.class),

+        @XmlElement(name = "schemeClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTSchemeColor.class),

+        @XmlElement(name = "prstClr", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPresetColor.class)

     })

     protected List<Object> egColorChoice;

 

@@ -79,12 +79,12 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

-     * {@link CTHslColor }

-     * {@link CTSRgbColor }

-     * {@link CTSchemeColor }

      * {@link CTScRgbColor }

-     * {@link CTPresetColor }

+     * {@link CTSRgbColor }

+     * {@link CTHslColor }

      * {@link CTSystemColor }

+     * {@link CTSchemeColor }

+     * {@link CTPresetColor }

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTComplementTransform.java b/src/java/org/apache/poi/sl/draw/binding/CTComplementTransform.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTComplementTransform.java
rename to src/java/org/apache/poi/sl/draw/binding/CTComplementTransform.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnection.java b/src/java/org/apache/poi/sl/draw/binding/CTConnection.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnection.java
rename to src/java/org/apache/poi/sl/draw/binding/CTConnection.java
index 4af3fac..f5d5e17 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnection.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTConnection.java
@@ -46,9 +46,9 @@
 @XmlType(name = "CT_Connection", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTConnection {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "id", required = true)

     protected long id;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "idx", required = true)

     @XmlSchemaType(name = "unsignedInt")

     protected long idx;

 

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnectionSite.java b/src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnectionSite.java
rename to src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java
index 7ec6297..eae59a0 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnectionSite.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTConnectionSite.java
@@ -52,7 +52,7 @@
 

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true)

     protected CTAdjPoint2D pos;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "ang", required = true)

     protected String ang;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java b/src/java/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java
rename to src/java/org/apache/poi/sl/draw/binding/CTConnectionSiteList.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java b/src/java/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTCustomGeometry2D.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java b/src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java
similarity index 94%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java
rename to src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java
index 94d44ec..8787125 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTEmbeddedWAVAudioFile.java
@@ -46,11 +46,11 @@
 @XmlType(name = "CT_EmbeddedWAVAudioFile", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTEmbeddedWAVAudioFile {

 

-    @XmlAttribute(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", required = true)

+    @XmlAttribute(name = "embed", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", required = true)

     protected String embed;

-    @XmlAttribute

+    @XmlAttribute(name = "name")

     protected String name;

-    @XmlAttribute

+    @XmlAttribute(name = "builtIn")

     protected Boolean builtIn;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTFixedPercentage.java b/src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTFixedPercentage.java
rename to src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java
index 92f41ae..d1ed283 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTFixedPercentage.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTFixedPercentage.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_FixedPercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTFixedPercentage {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGammaTransform.java b/src/java/org/apache/poi/sl/draw/binding/CTGammaTransform.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGammaTransform.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGammaTransform.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomGuide.java b/src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomGuide.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java
index 3df2209..5622e4c 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomGuide.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTGeomGuide.java
@@ -47,10 +47,10 @@
 @XmlType(name = "CT_GeomGuide", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTGeomGuide {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "name", required = true)

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String name;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "fmla", required = true)

     protected String fmla;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomGuideList.java b/src/java/org/apache/poi/sl/draw/binding/CTGeomGuideList.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomGuideList.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGeomGuideList.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomRect.java b/src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java
similarity index 95%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomRect.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java
index b1368be..3198f04 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGeomRect.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTGeomRect.java
@@ -47,13 +47,13 @@
 @XmlType(name = "CT_GeomRect", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTGeomRect {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "l", required = true)

     protected String l;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "t", required = true)

     protected String t;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "r", required = true)

     protected String r;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "b", required = true)

     protected String b;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java b/src/java/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGrayscaleTransform.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java b/src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java
index 6508613..f06e1d8 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTGroupTransform2D.java
@@ -66,11 +66,11 @@
     protected CTPoint2D chOff;

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

     protected CTPositiveSize2D chExt;

-    @XmlAttribute

+    @XmlAttribute(name = "rot")

     protected Integer rot;

-    @XmlAttribute

+    @XmlAttribute(name = "flipH")

     protected Boolean flipH;

-    @XmlAttribute

+    @XmlAttribute(name = "flipV")

     protected Boolean flipV;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHslColor.java b/src/java/org/apache/poi/sl/draw/binding/CTHslColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHslColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTHslColor.java
index c5bca5a..376d423 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHslColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTHslColor.java
@@ -57,41 +57,41 @@
 public class CTHslColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "hue", required = true)

     protected int hue;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "sat", required = true)

     protected int sat;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "lum", required = true)

     protected int lum;

 

     /**

@@ -112,34 +112,34 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHyperlink.java b/src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHyperlink.java
rename to src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java
index 03e486a..0c89f39 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTHyperlink.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTHyperlink.java
@@ -63,21 +63,21 @@
     protected CTEmbeddedWAVAudioFile snd;

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

     protected CTOfficeArtExtensionList extLst;

-    @XmlAttribute(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships")

+    @XmlAttribute(name = "id", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships")

     protected String id;

-    @XmlAttribute

+    @XmlAttribute(name = "invalidUrl")

     protected String invalidUrl;

-    @XmlAttribute

+    @XmlAttribute(name = "action")

     protected String action;

-    @XmlAttribute

+    @XmlAttribute(name = "tgtFrame")

     protected String tgtFrame;

-    @XmlAttribute

+    @XmlAttribute(name = "tooltip")

     protected String tooltip;

-    @XmlAttribute

+    @XmlAttribute(name = "history")

     protected Boolean history;

-    @XmlAttribute

+    @XmlAttribute(name = "highlightClick")

     protected Boolean highlightClick;

-    @XmlAttribute

+    @XmlAttribute(name = "endSnd")

     protected Boolean endSnd;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java b/src/java/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java
rename to src/java/org/apache/poi/sl/draw/binding/CTInverseGammaTransform.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTInverseTransform.java b/src/java/org/apache/poi/sl/draw/binding/CTInverseTransform.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTInverseTransform.java
rename to src/java/org/apache/poi/sl/draw/binding/CTInverseTransform.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java b/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java
rename to src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java
index adb928f..ec864d3 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtension.java
@@ -56,7 +56,7 @@
 

     @XmlAnyElement(lax = true)

     protected Object any;

-    @XmlAttribute

+    @XmlAttribute(name = "uri")

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     @XmlSchemaType(name = "token")

     protected String uri;

@@ -66,8 +66,8 @@
      * 

      * @return

      *     possible object is

-     *     {@link Element }

      *     {@link Object }

+     *     {@link Element }

      *     

      */

     public Object getAny() {

@@ -79,8 +79,8 @@
      * 

      * @param value

      *     allowed object is

-     *     {@link Element }

      *     {@link Object }

+     *     {@link Element }

      *     

      */

     public void setAny(Object value) {

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java b/src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java
rename to src/java/org/apache/poi/sl/draw/binding/CTOfficeArtExtensionList.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2D.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2D.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2D.java
index 84b9198..5294812 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPath2D.java
@@ -63,23 +63,23 @@
 public class CTPath2D {

 

     @XmlElements({

+        @XmlElement(name = "close", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DClose.class),

         @XmlElement(name = "moveTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DMoveTo.class),

-        @XmlElement(name = "quadBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DQuadBezierTo.class),

-        @XmlElement(name = "cubicBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DCubicBezierTo.class),

-        @XmlElement(name = "arcTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DArcTo.class),

         @XmlElement(name = "lnTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DLineTo.class),

-        @XmlElement(name = "close", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DClose.class)

+        @XmlElement(name = "arcTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DArcTo.class),

+        @XmlElement(name = "quadBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DQuadBezierTo.class),

+        @XmlElement(name = "cubicBezTo", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = CTPath2DCubicBezierTo.class)

     })

     protected List<Object> closeOrMoveToOrLnTo;

-    @XmlAttribute

+    @XmlAttribute(name = "w")

     protected Long w;

-    @XmlAttribute

+    @XmlAttribute(name = "h")

     protected Long h;

-    @XmlAttribute

+    @XmlAttribute(name = "fill")

     protected STPathFillMode fill;

-    @XmlAttribute

+    @XmlAttribute(name = "stroke")

     protected Boolean stroke;

-    @XmlAttribute

+    @XmlAttribute(name = "extrusionOk")

     protected Boolean extrusionOk;

 

     /**

@@ -100,12 +100,12 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

+     * {@link CTPath2DClose }

      * {@link CTPath2DMoveTo }

+     * {@link CTPath2DLineTo }

+     * {@link CTPath2DArcTo }

      * {@link CTPath2DQuadBezierTo }

      * {@link CTPath2DCubicBezierTo }

-     * {@link CTPath2DArcTo }

-     * {@link CTPath2DLineTo }

-     * {@link CTPath2DClose }

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java
index a4c325a..5464ee4 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPath2DArcTo.java
@@ -51,9 +51,9 @@
     protected String wr;

     @XmlAttribute(name = "hR", required = true)

     protected String hr;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "stAng", required = true)

     protected String stAng;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "swAng", required = true)

     protected String swAng;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DClose.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DClose.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DClose.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DClose.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DCubicBezierTo.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DLineTo.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DList.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DList.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DList.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DList.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DMoveTo.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java b/src/java/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPath2DQuadBezierTo.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPercentage.java b/src/java/org/apache/poi/sl/draw/binding/CTPercentage.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPercentage.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPercentage.java
index 7ca8c1f..e1a74b5 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPercentage.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPercentage.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_Percentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPercentage {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint2D.java b/src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java
index ae87986..06cbfbc 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPoint2D.java
@@ -45,9 +45,9 @@
 @XmlType(name = "CT_Point2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPoint2D {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "x", required = true)

     protected long x;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "y", required = true)

     protected long y;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint3D.java b/src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java
similarity index 95%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint3D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java
index e14c6ba..3cbeb67 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPoint3D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPoint3D.java
@@ -46,11 +46,11 @@
 @XmlType(name = "CT_Point3D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPoint3D {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "x", required = true)

     protected long x;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "y", required = true)

     protected long y;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "z", required = true)

     protected long z;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java b/src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java
index 9547ca9..646dad5 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPolarAdjustHandle.java
@@ -59,19 +59,19 @@
 

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true)

     protected CTAdjPoint2D pos;

-    @XmlAttribute

+    @XmlAttribute(name = "gdRefR")

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String gdRefR;

-    @XmlAttribute

+    @XmlAttribute(name = "minR")

     protected String minR;

-    @XmlAttribute

+    @XmlAttribute(name = "maxR")

     protected String maxR;

-    @XmlAttribute

+    @XmlAttribute(name = "gdRefAng")

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String gdRefAng;

-    @XmlAttribute

+    @XmlAttribute(name = "minAng")

     protected String minAng;

-    @XmlAttribute

+    @XmlAttribute(name = "maxAng")

     protected String maxAng;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java b/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java
index 94348d9..962db95 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedAngle.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_PositiveFixedAngle", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPositiveFixedAngle {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java b/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java
index de65915..001f01a 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPositiveFixedPercentage.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_PositiveFixedPercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPositiveFixedPercentage {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositivePercentage.java b/src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositivePercentage.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java
index 7b377e1..8fc61f3 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositivePercentage.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPositivePercentage.java
@@ -44,7 +44,7 @@
 @XmlType(name = "CT_PositivePercentage", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPositivePercentage {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected int val;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java b/src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java
index 210fd92..c8d76e6 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPositiveSize2D.java
@@ -45,9 +45,9 @@
 @XmlType(name = "CT_PositiveSize2D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTPositiveSize2D {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "cx", required = true)

     protected long cx;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "cy", required = true)

     protected long cy;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetColor.java b/src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java
index 991d232..e240a71 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPresetColor.java
@@ -55,37 +55,37 @@
 public class CTPresetColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute

+    @XmlAttribute(name = "val")

     protected STPresetColorVal val;

 

     /**

@@ -106,34 +106,34 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java b/src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java
index 234bbd9..b55b02e 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPresetGeometry2D.java
@@ -52,7 +52,7 @@
 

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

     protected CTGeomGuideList avLst;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "prst", required = true)

     protected STShapeType prst;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetTextShape.java b/src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetTextShape.java
rename to src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java
index 0a6135f..f7082b3 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTPresetTextShape.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTPresetTextShape.java
@@ -52,7 +52,7 @@
 

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

     protected CTGeomGuideList avLst;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "prst", required = true)

     protected STTextShapeType prst;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRatio.java b/src/java/org/apache/poi/sl/draw/binding/CTRatio.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRatio.java
rename to src/java/org/apache/poi/sl/draw/binding/CTRatio.java
index 4a61b88..3a951c1 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRatio.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTRatio.java
@@ -45,9 +45,9 @@
 @XmlType(name = "CT_Ratio", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTRatio {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "n", required = true)

     protected long n;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "d", required = true)

     protected long d;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRelativeRect.java b/src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java
similarity index 97%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRelativeRect.java
rename to src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java
index a8b82c4..e332bd8 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTRelativeRect.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTRelativeRect.java
@@ -47,13 +47,13 @@
 @XmlType(name = "CT_RelativeRect", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTRelativeRect {

 

-    @XmlAttribute

+    @XmlAttribute(name = "l")

     protected Integer l;

-    @XmlAttribute

+    @XmlAttribute(name = "t")

     protected Integer t;

-    @XmlAttribute

+    @XmlAttribute(name = "r")

     protected Integer r;

-    @XmlAttribute

+    @XmlAttribute(name = "b")

     protected Integer b;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSRgbColor.java b/src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSRgbColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java
index c48e837..ef920d6 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSRgbColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTSRgbColor.java
@@ -57,37 +57,37 @@
 public class CTSRgbColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     @XmlJavaTypeAdapter(HexBinaryAdapter.class)

     protected byte[] val;

 

@@ -109,34 +109,34 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

-     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

      * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

      * 

      * 

      */

@@ -176,7 +176,7 @@
      *     

      */

     public void setVal(byte[] value) {

-        this.val = ((byte[]) value);

+        this.val = value;

     }

 

     public boolean isSetVal() {

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTScRgbColor.java b/src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTScRgbColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java
index 4168027..335e4b2 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTScRgbColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTScRgbColor.java
@@ -57,41 +57,41 @@
 public class CTScRgbColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "r", required = true)

     protected int r;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "g", required = true)

     protected int g;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "b", required = true)

     protected int b;

 

     /**

@@ -113,33 +113,33 @@
      * <p>

      * Objects of the following type(s) are allowed in the list

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTScale2D.java b/src/java/org/apache/poi/sl/draw/binding/CTScale2D.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTScale2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTScale2D.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSchemeColor.java b/src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSchemeColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java
index b93a166..7febaad 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSchemeColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTSchemeColor.java
@@ -55,37 +55,37 @@
 public class CTSchemeColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     protected STSchemeColorVal val;

 

     /**

@@ -106,34 +106,34 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

-     * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

      * 

      * 

      */

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSphereCoords.java b/src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java
similarity index 95%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSphereCoords.java
rename to src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java
index 7f03d0d..a29d744 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSphereCoords.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTSphereCoords.java
@@ -46,11 +46,11 @@
 @XmlType(name = "CT_SphereCoords", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTSphereCoords {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "lat", required = true)

     protected int lat;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "lon", required = true)

     protected int lon;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "rev", required = true)

     protected int rev;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSystemColor.java b/src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java
similarity index 92%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSystemColor.java
rename to src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java
index de94cb2..adf0d16 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTSystemColor.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTSystemColor.java
@@ -59,40 +59,40 @@
 public class CTSystemColor {

 

     @XmlElementRefs({

-        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class),

-        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class)

+        @XmlElementRef(name = "alphaMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lum", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "sat", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "red", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "invGamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "comp", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "lumOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "greenOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alphaOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "green", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "inv", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "alpha", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "shade", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "blue", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "redMod", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "hueOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gray", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "gamma", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "tint", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false),

+        @XmlElementRef(name = "satOff", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", type = JAXBElement.class, required = false)

     })

     protected List<JAXBElement<?>> egColorTransform;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "val", required = true)

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String val;

-    @XmlAttribute

+    @XmlAttribute(name = "lastClr")

     @XmlJavaTypeAdapter(HexBinaryAdapter.class)

     protected byte[] lastClr;

 

@@ -114,34 +114,34 @@
      * 

      * <p>

      * Objects of the following type(s) are allowed in the list

+     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

      * {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}

      * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}

-     * {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}

+     * {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}

      * 

      * 

      */

@@ -209,7 +209,7 @@
      *     

      */

     public void setLastClr(byte[] value) {

-        this.lastClr = ((byte[]) value);

+        this.lastClr = value;

     }

 

     public boolean isSetLastClr() {

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTTransform2D.java b/src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java
similarity index 98%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTTransform2D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java
index dd1dcb5..38ec50e 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTTransform2D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTTransform2D.java
@@ -58,11 +58,11 @@
     protected CTPoint2D off;

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

     protected CTPositiveSize2D ext;

-    @XmlAttribute

+    @XmlAttribute(name = "rot")

     protected Integer rot;

-    @XmlAttribute

+    @XmlAttribute(name = "flipH")

     protected Boolean flipH;

-    @XmlAttribute

+    @XmlAttribute(name = "flipV")

     protected Boolean flipV;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTVector3D.java b/src/java/org/apache/poi/sl/draw/binding/CTVector3D.java
similarity index 95%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTVector3D.java
rename to src/java/org/apache/poi/sl/draw/binding/CTVector3D.java
index d7f744b..03c5fb8 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTVector3D.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTVector3D.java
@@ -46,11 +46,11 @@
 @XmlType(name = "CT_Vector3D", namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")

 public class CTVector3D {

 

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "dx", required = true)

     protected long dx;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "dy", required = true)

     protected long dy;

-    @XmlAttribute(required = true)

+    @XmlAttribute(name = "dz", required = true)

     protected long dz;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java b/src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java
similarity index 96%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java
rename to src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java
index 2b22a58..85c30ba 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java
+++ b/src/java/org/apache/poi/sl/draw/binding/CTXYAdjustHandle.java
@@ -59,19 +59,19 @@
 

     @XmlElement(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", required = true)

     protected CTAdjPoint2D pos;

-    @XmlAttribute

+    @XmlAttribute(name = "gdRefX")

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String gdRefX;

-    @XmlAttribute

+    @XmlAttribute(name = "minX")

     protected String minX;

-    @XmlAttribute

+    @XmlAttribute(name = "maxX")

     protected String maxX;

-    @XmlAttribute

+    @XmlAttribute(name = "gdRefY")

     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)

     protected String gdRefY;

-    @XmlAttribute

+    @XmlAttribute(name = "minY")

     protected String minY;

-    @XmlAttribute

+    @XmlAttribute(name = "maxY")

     protected String maxY;

 

     /**

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/ObjectFactory.java b/src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java
similarity index 76%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/ObjectFactory.java
rename to src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java
index c8c8c19..8c6f9c2 100644
--- a/src/scratchpad/src/org/apache/poi/sl/draw/binding/ObjectFactory.java
+++ b/src/java/org/apache/poi/sl/draw/binding/ObjectFactory.java
@@ -40,34 +40,34 @@
 @XmlRegistry

 public class ObjectFactory {

 

-    private final static QName _CTScRgbColorAlpha_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alpha");

-    private final static QName _CTScRgbColorLum_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lum");

-    private final static QName _CTScRgbColorGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gamma");

-    private final static QName _CTScRgbColorInvGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "invGamma");

-    private final static QName _CTScRgbColorAlphaMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaMod");

-    private final static QName _CTScRgbColorRedOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redOff");

-    private final static QName _CTScRgbColorAlphaOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaOff");

-    private final static QName _CTScRgbColorGreenOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenOff");

-    private final static QName _CTScRgbColorRedMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redMod");

-    private final static QName _CTScRgbColorHue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hue");

-    private final static QName _CTScRgbColorSatOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satOff");

-    private final static QName _CTScRgbColorGreenMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenMod");

-    private final static QName _CTScRgbColorSat_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "sat");

-    private final static QName _CTScRgbColorBlue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blue");

-    private final static QName _CTScRgbColorRed_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "red");

-    private final static QName _CTScRgbColorSatMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satMod");

-    private final static QName _CTScRgbColorHueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueOff");

-    private final static QName _CTScRgbColorBlueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueMod");

-    private final static QName _CTScRgbColorShade_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "shade");

-    private final static QName _CTScRgbColorLumMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumMod");

-    private final static QName _CTScRgbColorInv_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "inv");

-    private final static QName _CTScRgbColorLumOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumOff");

-    private final static QName _CTScRgbColorTint_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tint");

-    private final static QName _CTScRgbColorGreen_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "green");

-    private final static QName _CTScRgbColorComp_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "comp");

-    private final static QName _CTScRgbColorBlueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueOff");

-    private final static QName _CTScRgbColorHueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueMod");

-    private final static QName _CTScRgbColorGray_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gray");

+    private final static QName _CTSRgbColorAlpha_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alpha");

+    private final static QName _CTSRgbColorLum_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lum");

+    private final static QName _CTSRgbColorGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gamma");

+    private final static QName _CTSRgbColorInvGamma_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "invGamma");

+    private final static QName _CTSRgbColorAlphaMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaMod");

+    private final static QName _CTSRgbColorRedOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redOff");

+    private final static QName _CTSRgbColorAlphaOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "alphaOff");

+    private final static QName _CTSRgbColorGreenOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenOff");

+    private final static QName _CTSRgbColorHue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hue");

+    private final static QName _CTSRgbColorRedMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "redMod");

+    private final static QName _CTSRgbColorSatOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satOff");

+    private final static QName _CTSRgbColorGreenMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "greenMod");

+    private final static QName _CTSRgbColorSat_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "sat");

+    private final static QName _CTSRgbColorBlue_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blue");

+    private final static QName _CTSRgbColorRed_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "red");

+    private final static QName _CTSRgbColorSatMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "satMod");

+    private final static QName _CTSRgbColorBlueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueMod");

+    private final static QName _CTSRgbColorHueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueOff");

+    private final static QName _CTSRgbColorShade_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "shade");

+    private final static QName _CTSRgbColorLumMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumMod");

+    private final static QName _CTSRgbColorInv_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "inv");

+    private final static QName _CTSRgbColorLumOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "lumOff");

+    private final static QName _CTSRgbColorTint_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tint");

+    private final static QName _CTSRgbColorGreen_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "green");

+    private final static QName _CTSRgbColorComp_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "comp");

+    private final static QName _CTSRgbColorBlueOff_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "blueOff");

+    private final static QName _CTSRgbColorHueMod_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "hueMod");

+    private final static QName _CTSRgbColorGray_QNAME = new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "gray");

 

     /**

      * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.poi.sl.draw.binding

@@ -77,62 +77,6 @@
     }

 

     /**

-     * Create an instance of {@link CTOfficeArtExtensionList }

-     * 

-     */

-    public CTOfficeArtExtensionList createCTOfficeArtExtensionList() {

-        return new CTOfficeArtExtensionList();

-    }

-

-    /**

-     * Create an instance of {@link CTPresetGeometry2D }

-     * 

-     */

-    public CTPresetGeometry2D createCTPresetGeometry2D() {

-        return new CTPresetGeometry2D();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2D }

-     * 

-     */

-    public CTPath2D createCTPath2D() {

-        return new CTPath2D();

-    }

-

-    /**

-     * Create an instance of {@link CTVector3D }

-     * 

-     */

-    public CTVector3D createCTVector3D() {

-        return new CTVector3D();

-    }

-

-    /**

-     * Create an instance of {@link CTGammaTransform }

-     * 

-     */

-    public CTGammaTransform createCTGammaTransform() {

-        return new CTGammaTransform();

-    }

-

-    /**

-     * Create an instance of {@link CTColorMRU }

-     * 

-     */

-    public CTColorMRU createCTColorMRU() {

-        return new CTColorMRU();

-    }

-

-    /**

-     * Create an instance of {@link CTEmbeddedWAVAudioFile }

-     * 

-     */

-    public CTEmbeddedWAVAudioFile createCTEmbeddedWAVAudioFile() {

-        return new CTEmbeddedWAVAudioFile();

-    }

-

-    /**

      * Create an instance of {@link CTPath2DQuadBezierTo }

      * 

      */

@@ -141,70 +85,6 @@
     }

 

     /**

-     * Create an instance of {@link CTScRgbColor }

-     * 

-     */

-    public CTScRgbColor createCTScRgbColor() {

-        return new CTScRgbColor();

-    }

-

-    /**

-     * Create an instance of {@link CTPositiveFixedAngle }

-     * 

-     */

-    public CTPositiveFixedAngle createCTPositiveFixedAngle() {

-        return new CTPositiveFixedAngle();

-    }

-

-    /**

-     * Create an instance of {@link CTGeomGuide }

-     * 

-     */

-    public CTGeomGuide createCTGeomGuide() {

-        return new CTGeomGuide();

-    }

-

-    /**

-     * Create an instance of {@link CTConnectionSiteList }

-     * 

-     */

-    public CTConnectionSiteList createCTConnectionSiteList() {

-        return new CTConnectionSiteList();

-    }

-

-    /**

-     * Create an instance of {@link CTPercentage }

-     * 

-     */

-    public CTPercentage createCTPercentage() {

-        return new CTPercentage();

-    }

-

-    /**

-     * Create an instance of {@link CTPositiveFixedPercentage }

-     * 

-     */

-    public CTPositiveFixedPercentage createCTPositiveFixedPercentage() {

-        return new CTPositiveFixedPercentage();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2DMoveTo }

-     * 

-     */

-    public CTPath2DMoveTo createCTPath2DMoveTo() {

-        return new CTPath2DMoveTo();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2DList }

-     * 

-     */

-    public CTPath2DList createCTPath2DList() {

-        return new CTPath2DList();

-    }

-

-    /**

      * Create an instance of {@link CTCustomGeometry2D }

      * 

      */

@@ -213,46 +93,6 @@
     }

 

     /**

-     * Create an instance of {@link CTConnectionSite }

-     * 

-     */

-    public CTConnectionSite createCTConnectionSite() {

-        return new CTConnectionSite();

-    }

-

-    /**

-     * Create an instance of {@link CTGrayscaleTransform }

-     * 

-     */

-    public CTGrayscaleTransform createCTGrayscaleTransform() {

-        return new CTGrayscaleTransform();

-    }

-

-    /**

-     * Create an instance of {@link CTInverseTransform }

-     * 

-     */

-    public CTInverseTransform createCTInverseTransform() {

-        return new CTInverseTransform();

-    }

-

-    /**

-     * Create an instance of {@link CTPositiveSize2D }

-     * 

-     */

-    public CTPositiveSize2D createCTPositiveSize2D() {

-        return new CTPositiveSize2D();

-    }

-

-    /**

-     * Create an instance of {@link CTRelativeRect }

-     * 

-     */

-    public CTRelativeRect createCTRelativeRect() {

-        return new CTRelativeRect();

-    }

-

-    /**

      * Create an instance of {@link CTPolarAdjustHandle }

      * 

      */

@@ -261,86 +101,6 @@
     }

 

     /**

-     * Create an instance of {@link CTRatio }

-     * 

-     */

-    public CTRatio createCTRatio() {

-        return new CTRatio();

-    }

-

-    /**

-     * Create an instance of {@link CTInverseGammaTransform }

-     * 

-     */

-    public CTInverseGammaTransform createCTInverseGammaTransform() {

-        return new CTInverseGammaTransform();

-    }

-

-    /**

-     * Create an instance of {@link CTGroupTransform2D }

-     * 

-     */

-    public CTGroupTransform2D createCTGroupTransform2D() {

-        return new CTGroupTransform2D();

-    }

-

-    /**

-     * Create an instance of {@link CTGeomRect }

-     * 

-     */

-    public CTGeomRect createCTGeomRect() {

-        return new CTGeomRect();

-    }

-

-    /**

-     * Create an instance of {@link CTSystemColor }

-     * 

-     */

-    public CTSystemColor createCTSystemColor() {

-        return new CTSystemColor();

-    }

-

-    /**

-     * Create an instance of {@link CTAdjPoint2D }

-     * 

-     */

-    public CTAdjPoint2D createCTAdjPoint2D() {

-        return new CTAdjPoint2D();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2DCubicBezierTo }

-     * 

-     */

-    public CTPath2DCubicBezierTo createCTPath2DCubicBezierTo() {

-        return new CTPath2DCubicBezierTo();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2DArcTo }

-     * 

-     */

-    public CTPath2DArcTo createCTPath2DArcTo() {

-        return new CTPath2DArcTo();

-    }

-

-    /**

-     * Create an instance of {@link CTGeomGuideList }

-     * 

-     */

-    public CTGeomGuideList createCTGeomGuideList() {

-        return new CTGeomGuideList();

-    }

-

-    /**

-     * Create an instance of {@link CTAdjustHandleList }

-     * 

-     */

-    public CTAdjustHandleList createCTAdjustHandleList() {

-        return new CTAdjustHandleList();

-    }

-

-    /**

      * Create an instance of {@link CTPath2DClose }

      * 

      */

@@ -349,62 +109,6 @@
     }

 

     /**

-     * Create an instance of {@link CTPresetTextShape }

-     * 

-     */

-    public CTPresetTextShape createCTPresetTextShape() {

-        return new CTPresetTextShape();

-    }

-

-    /**

-     * Create an instance of {@link CTConnection }

-     * 

-     */

-    public CTConnection createCTConnection() {

-        return new CTConnection();

-    }

-

-    /**

-     * Create an instance of {@link CTSRgbColor }

-     * 

-     */

-    public CTSRgbColor createCTSRgbColor() {

-        return new CTSRgbColor();

-    }

-

-    /**

-     * Create an instance of {@link CTPositivePercentage }

-     * 

-     */

-    public CTPositivePercentage createCTPositivePercentage() {

-        return new CTPositivePercentage();

-    }

-

-    /**

-     * Create an instance of {@link CTComplementTransform }

-     * 

-     */

-    public CTComplementTransform createCTComplementTransform() {

-        return new CTComplementTransform();

-    }

-

-    /**

-     * Create an instance of {@link CTScale2D }

-     * 

-     */

-    public CTScale2D createCTScale2D() {

-        return new CTScale2D();

-    }

-

-    /**

-     * Create an instance of {@link CTFixedPercentage }

-     * 

-     */

-    public CTFixedPercentage createCTFixedPercentage() {

-        return new CTFixedPercentage();

-    }

-

-    /**

      * Create an instance of {@link CTPoint2D }

      * 

      */

@@ -413,6 +117,38 @@
     }

 

     /**

+     * Create an instance of {@link CTInverseTransform }

+     * 

+     */

+    public CTInverseTransform createCTInverseTransform() {

+        return new CTInverseTransform();

+    }

+

+    /**

+     * Create an instance of {@link CTPercentage }

+     * 

+     */

+    public CTPercentage createCTPercentage() {

+        return new CTPercentage();

+    }

+

+    /**

+     * Create an instance of {@link CTSystemColor }

+     * 

+     */

+    public CTSystemColor createCTSystemColor() {

+        return new CTSystemColor();

+    }

+

+    /**

+     * Create an instance of {@link CTConnectionSite }

+     * 

+     */

+    public CTConnectionSite createCTConnectionSite() {

+        return new CTConnectionSite();

+    }

+

+    /**

      * Create an instance of {@link CTColor }

      * 

      */

@@ -421,11 +157,19 @@
     }

 

     /**

-     * Create an instance of {@link CTPoint3D }

+     * Create an instance of {@link CTPositiveFixedAngle }

      * 

      */

-    public CTPoint3D createCTPoint3D() {

-        return new CTPoint3D();

+    public CTPositiveFixedAngle createCTPositiveFixedAngle() {

+        return new CTPositiveFixedAngle();

+    }

+

+    /**

+     * Create an instance of {@link CTFixedPercentage }

+     * 

+     */

+    public CTFixedPercentage createCTFixedPercentage() {

+        return new CTFixedPercentage();

     }

 

     /**

@@ -437,6 +181,22 @@
     }

 

     /**

+     * Create an instance of {@link CTConnection }

+     * 

+     */

+    public CTConnection createCTConnection() {

+        return new CTConnection();

+    }

+

+    /**

+     * Create an instance of {@link CTPath2DLineTo }

+     * 

+     */

+    public CTPath2DLineTo createCTPath2DLineTo() {

+        return new CTPath2DLineTo();

+    }

+

+    /**

      * Create an instance of {@link CTTransform2D }

      * 

      */

@@ -445,6 +205,110 @@
     }

 

     /**

+     * Create an instance of {@link CTPositivePercentage }

+     * 

+     */

+    public CTPositivePercentage createCTPositivePercentage() {

+        return new CTPositivePercentage();

+    }

+

+    /**

+     * Create an instance of {@link CTVector3D }

+     * 

+     */

+    public CTVector3D createCTVector3D() {

+        return new CTVector3D();

+    }

+

+    /**

+     * Create an instance of {@link CTSphereCoords }

+     * 

+     */

+    public CTSphereCoords createCTSphereCoords() {

+        return new CTSphereCoords();

+    }

+

+    /**

+     * Create an instance of {@link CTPath2D }

+     * 

+     */

+    public CTPath2D createCTPath2D() {

+        return new CTPath2D();

+    }

+

+    /**

+     * Create an instance of {@link CTGroupTransform2D }

+     * 

+     */

+    public CTGroupTransform2D createCTGroupTransform2D() {

+        return new CTGroupTransform2D();

+    }

+

+    /**

+     * Create an instance of {@link CTGrayscaleTransform }

+     * 

+     */

+    public CTGrayscaleTransform createCTGrayscaleTransform() {

+        return new CTGrayscaleTransform();

+    }

+

+    /**

+     * Create an instance of {@link CTRatio }

+     * 

+     */

+    public CTRatio createCTRatio() {

+        return new CTRatio();

+    }

+

+    /**

+     * Create an instance of {@link CTSRgbColor }

+     * 

+     */

+    public CTSRgbColor createCTSRgbColor() {

+        return new CTSRgbColor();

+    }

+

+    /**

+     * Create an instance of {@link CTGeomGuideList }

+     * 

+     */

+    public CTGeomGuideList createCTGeomGuideList() {

+        return new CTGeomGuideList();

+    }

+

+    /**

+     * Create an instance of {@link CTComplementTransform }

+     * 

+     */

+    public CTComplementTransform createCTComplementTransform() {

+        return new CTComplementTransform();

+    }

+

+    /**

+     * Create an instance of {@link CTPath2DCubicBezierTo }

+     * 

+     */

+    public CTPath2DCubicBezierTo createCTPath2DCubicBezierTo() {

+        return new CTPath2DCubicBezierTo();

+    }

+

+    /**

+     * Create an instance of {@link CTXYAdjustHandle }

+     * 

+     */

+    public CTXYAdjustHandle createCTXYAdjustHandle() {

+        return new CTXYAdjustHandle();

+    }

+

+    /**

+     * Create an instance of {@link CTPresetColor }

+     * 

+     */

+    public CTPresetColor createCTPresetColor() {

+        return new CTPresetColor();

+    }

+

+    /**

      * Create an instance of {@link CTOfficeArtExtension }

      * 

      */

@@ -461,43 +325,27 @@
     }

 

     /**

-     * Create an instance of {@link CTSphereCoords }

+     * Create an instance of {@link CTConnectionSiteList }

      * 

      */

-    public CTSphereCoords createCTSphereCoords() {

-        return new CTSphereCoords();

+    public CTConnectionSiteList createCTConnectionSiteList() {

+        return new CTConnectionSiteList();

     }

 

     /**

-     * Create an instance of {@link CTXYAdjustHandle }

+     * Create an instance of {@link CTPath2DArcTo }

      * 

      */

-    public CTXYAdjustHandle createCTXYAdjustHandle() {

-        return new CTXYAdjustHandle();

+    public CTPath2DArcTo createCTPath2DArcTo() {

+        return new CTPath2DArcTo();

     }

 

     /**

-     * Create an instance of {@link CTHyperlink }

+     * Create an instance of {@link CTPath2DList }

      * 

      */

-    public CTHyperlink createCTHyperlink() {

-        return new CTHyperlink();

-    }

-

-    /**

-     * Create an instance of {@link CTPath2DLineTo }

-     * 

-     */

-    public CTPath2DLineTo createCTPath2DLineTo() {

-        return new CTPath2DLineTo();

-    }

-

-    /**

-     * Create an instance of {@link CTPresetColor }

-     * 

-     */

-    public CTPresetColor createCTPresetColor() {

-        return new CTPresetColor();

+    public CTPath2DList createCTPath2DList() {

+        return new CTPath2DList();

     }

 

     /**

@@ -509,1011 +357,155 @@
     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * Create an instance of {@link CTScale2D }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

+    public CTScale2D createCTScale2D() {

+        return new CTScale2D();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTPositiveSize2D }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTPositiveSize2D createCTPositiveSize2D() {

+        return new CTPositiveSize2D();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

+     * Create an instance of {@link CTOfficeArtExtensionList }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTScRgbColor.class)

-    public JAXBElement<CTGammaTransform> createCTScRgbColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTScRgbColor.class, value);

+    public CTOfficeArtExtensionList createCTOfficeArtExtensionList() {

+        return new CTOfficeArtExtensionList();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

+     * Create an instance of {@link CTHyperlink }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTScRgbColor.class)

-    public JAXBElement<CTInverseGammaTransform> createCTScRgbColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTScRgbColor.class, value);

+    public CTHyperlink createCTHyperlink() {

+        return new CTHyperlink();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * Create an instance of {@link CTPoint3D }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositivePercentage> createCTScRgbColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value);

+    public CTPoint3D createCTPoint3D() {

+        return new CTPoint3D();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTInverseGammaTransform }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTInverseGammaTransform createCTInverseGammaTransform() {

+        return new CTInverseGammaTransform();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

+     * Create an instance of {@link CTPositiveFixedPercentage }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTFixedPercentage> createCTScRgbColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTScRgbColor.class, value);

+    public CTPositiveFixedPercentage createCTPositiveFixedPercentage() {

+        return new CTPositiveFixedPercentage();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTGeomRect }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTGeomRect createCTGeomRect() {

+        return new CTGeomRect();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTPresetTextShape }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTPresetTextShape createCTPresetTextShape() {

+        return new CTPresetTextShape();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

+     * Create an instance of {@link CTColorMRU }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositiveFixedAngle> createCTScRgbColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTScRgbColor.class, value);

+    public CTColorMRU createCTColorMRU() {

+        return new CTColorMRU();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTPath2DMoveTo }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTPath2DMoveTo createCTPath2DMoveTo() {

+        return new CTPath2DMoveTo();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTEmbeddedWAVAudioFile }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTEmbeddedWAVAudioFile createCTEmbeddedWAVAudioFile() {

+        return new CTEmbeddedWAVAudioFile();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTScRgbColor }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTScRgbColor createCTScRgbColor() {

+        return new CTScRgbColor();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTPresetGeometry2D }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTPresetGeometry2D createCTPresetGeometry2D() {

+        return new CTPresetGeometry2D();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTGeomGuide }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTGeomGuide createCTGeomGuide() {

+        return new CTGeomGuide();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTRelativeRect }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTRelativeRect createCTRelativeRect() {

+        return new CTRelativeRect();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * Create an instance of {@link CTAdjustHandleList }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTAngle> createCTScRgbColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTScRgbColor.class, value);

+    public CTAdjustHandleList createCTAdjustHandleList() {

+        return new CTAdjustHandleList();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * Create an instance of {@link CTAdjPoint2D }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    public CTAdjPoint2D createCTAdjPoint2D() {

+        return new CTAdjPoint2D();

     }

 

     /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * Create an instance of {@link CTGammaTransform }

      * 

      */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTScRgbColor.class)

-    public JAXBElement<CTInverseTransform> createCTScRgbColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTScRgbColor.class)

-    public JAXBElement<CTComplementTransform> createCTScRgbColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTScRgbColor.class)

-    public JAXBElement<CTPercentage> createCTScRgbColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTScRgbColor.class)

-    public JAXBElement<CTPositivePercentage> createCTScRgbColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTScRgbColor.class)

-    public JAXBElement<CTGrayscaleTransform> createCTScRgbColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTScRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTHslColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTHslColor.class)

-    public JAXBElement<CTGammaTransform> createCTHslColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTHslColor.class)

-    public JAXBElement<CTInverseGammaTransform> createCTHslColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTHslColor.class)

-    public JAXBElement<CTPositivePercentage> createCTHslColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTHslColor.class)

-    public JAXBElement<CTFixedPercentage> createCTHslColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTHslColor.class)

-    public JAXBElement<CTPositiveFixedAngle> createCTHslColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTHslColor.class)

-    public JAXBElement<CTAngle> createCTHslColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTHslColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTHslColor.class)

-    public JAXBElement<CTInverseTransform> createCTHslColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTHslColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTHslColor.class)

-    public JAXBElement<CTComplementTransform> createCTHslColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTHslColor.class)

-    public JAXBElement<CTPercentage> createCTHslColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTHslColor.class)

-    public JAXBElement<CTPositivePercentage> createCTHslColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTHslColor.class)

-    public JAXBElement<CTGrayscaleTransform> createCTHslColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTHslColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSystemColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSystemColor.class)

-    public JAXBElement<CTGammaTransform> createCTSystemColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSystemColor.class)

-    public JAXBElement<CTInverseGammaTransform> createCTSystemColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPositivePercentage> createCTSystemColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSystemColor.class)

-    public JAXBElement<CTFixedPercentage> createCTSystemColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSystemColor.class)

-    public JAXBElement<CTPositiveFixedAngle> createCTSystemColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSystemColor.class)

-    public JAXBElement<CTAngle> createCTSystemColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSystemColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSystemColor.class)

-    public JAXBElement<CTInverseTransform> createCTSystemColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSystemColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSystemColor.class)

-    public JAXBElement<CTComplementTransform> createCTSystemColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSystemColor.class)

-    public JAXBElement<CTPercentage> createCTSystemColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSystemColor.class)

-    public JAXBElement<CTPositivePercentage> createCTSystemColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSystemColor.class)

-    public JAXBElement<CTGrayscaleTransform> createCTSystemColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSystemColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTPresetColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTPresetColor.class)

-    public JAXBElement<CTGammaTransform> createCTPresetColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTPresetColor.class)

-    public JAXBElement<CTInverseGammaTransform> createCTPresetColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPositivePercentage> createCTPresetColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTPresetColor.class)

-    public JAXBElement<CTFixedPercentage> createCTPresetColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTPresetColor.class)

-    public JAXBElement<CTPositiveFixedAngle> createCTPresetColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTPresetColor.class)

-    public JAXBElement<CTAngle> createCTPresetColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTPresetColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTPresetColor.class)

-    public JAXBElement<CTInverseTransform> createCTPresetColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTPresetColor.class)

-    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTPresetColor.class)

-    public JAXBElement<CTComplementTransform> createCTPresetColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTPresetColor.class)

-    public JAXBElement<CTPercentage> createCTPresetColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTPresetColor.class)

-    public JAXBElement<CTPositivePercentage> createCTPresetColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTPresetColor.class)

-    public JAXBElement<CTGrayscaleTransform> createCTPresetColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTPresetColor.class, value);

+    public CTGammaTransform createCTGammaTransform() {

+        return new CTGammaTransform();

     }

 

     /**

@@ -1522,7 +514,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSRgbColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSRgbColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1531,7 +523,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1540,7 +532,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSRgbColor.class)

     public JAXBElement<CTGammaTransform> createCTSRgbColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1549,7 +541,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSRgbColor.class)

     public JAXBElement<CTInverseGammaTransform> createCTSRgbColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1558,7 +550,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPositivePercentage> createCTSRgbColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1567,7 +559,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1576,7 +568,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSRgbColor.class)

     public JAXBElement<CTFixedPercentage> createCTSRgbColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1585,16 +577,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSRgbColor.class)

-    public JAXBElement<CTPercentage> createCTSRgbColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1603,7 +586,16 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSRgbColor.class)

     public JAXBElement<CTPositiveFixedAngle> createCTSRgbColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSRgbColor.class)

+    public JAXBElement<CTPercentage> createCTSRgbColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1612,7 +604,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1621,16 +613,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSRgbColor.class)

-    public JAXBElement<CTPercentage> createCTSRgbColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1639,7 +622,16 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSRgbColor.class)

+    public JAXBElement<CTPercentage> createCTSRgbColorBlue(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1648,7 +640,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1657,16 +649,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSRgbColor.class)

-    public JAXBElement<CTAngle> createCTSRgbColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1675,7 +658,16 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSRgbColor.class)

+    public JAXBElement<CTAngle> createCTSRgbColorHueOff(CTAngle value) {

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1684,7 +676,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSRgbColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSRgbColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1693,7 +685,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1702,7 +694,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSRgbColor.class)

     public JAXBElement<CTInverseTransform> createCTSRgbColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1711,7 +703,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1720,7 +712,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSRgbColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSRgbColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1729,7 +721,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1738,7 +730,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSRgbColor.class)

     public JAXBElement<CTComplementTransform> createCTSRgbColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1747,7 +739,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSRgbColor.class)

     public JAXBElement<CTPercentage> createCTSRgbColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1756,7 +748,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSRgbColor.class)

     public JAXBElement<CTPositivePercentage> createCTSRgbColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1765,7 +757,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSRgbColor.class)

     public JAXBElement<CTGrayscaleTransform> createCTSRgbColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSRgbColor.class, value);

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSRgbColor.class, value);

     }

 

     /**

@@ -1774,7 +766,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSchemeColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSchemeColorAlpha(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1783,7 +775,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorLum(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLum_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1792,7 +784,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSchemeColor.class)

     public JAXBElement<CTGammaTransform> createCTSchemeColorGamma(CTGammaTransform value) {

-        return new JAXBElement<CTGammaTransform>(_CTScRgbColorGamma_QNAME, CTGammaTransform.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1801,16 +793,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSchemeColor.class)

     public JAXBElement<CTInverseGammaTransform> createCTSchemeColorInvGamma(CTInverseGammaTransform value) {

-        return new JAXBElement<CTInverseGammaTransform>(_CTScRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSchemeColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSchemeColor.class)

-    public JAXBElement<CTPercentage> createCTSchemeColorRedOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1819,7 +802,16 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPositivePercentage> createCTSchemeColorAlphaMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSchemeColor.class)

+    public JAXBElement<CTPercentage> createCTSchemeColorRedOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1828,7 +820,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSchemeColor.class)

     public JAXBElement<CTFixedPercentage> createCTSchemeColorAlphaOff(CTFixedPercentage value) {

-        return new JAXBElement<CTFixedPercentage>(_CTScRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1837,16 +829,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorGreenOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

-    }

-

-    /**

-     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

-     * 

-     */

-    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSchemeColor.class)

-    public JAXBElement<CTPercentage> createCTSchemeColorRedMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRedMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1855,7 +838,16 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSchemeColor.class)

     public JAXBElement<CTPositiveFixedAngle> createCTSchemeColorHue(CTPositiveFixedAngle value) {

-        return new JAXBElement<CTPositiveFixedAngle>(_CTScRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSchemeColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSchemeColor.class)

+    public JAXBElement<CTPercentage> createCTSchemeColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1864,7 +856,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorSatOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1873,7 +865,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorGreenMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreenMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1882,7 +874,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorSat(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSat_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1891,7 +883,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorBlue(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlue_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1900,7 +892,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorRed(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorRed_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1909,7 +901,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorSatMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorSatMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1918,7 +910,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorBlueMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1927,7 +919,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSchemeColor.class)

     public JAXBElement<CTAngle> createCTSchemeColorHueOff(CTAngle value) {

-        return new JAXBElement<CTAngle>(_CTScRgbColorHueOff_QNAME, CTAngle.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1936,7 +928,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSchemeColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSchemeColorShade(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1945,7 +937,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorLumMod(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1954,7 +946,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSchemeColor.class)

     public JAXBElement<CTInverseTransform> createCTSchemeColorInv(CTInverseTransform value) {

-        return new JAXBElement<CTInverseTransform>(_CTScRgbColorInv_QNAME, CTInverseTransform.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1963,7 +955,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorLumOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorLumOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1972,7 +964,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSchemeColor.class)

     public JAXBElement<CTPositiveFixedPercentage> createCTSchemeColorTint(CTPositiveFixedPercentage value) {

-        return new JAXBElement<CTPositiveFixedPercentage>(_CTScRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1981,7 +973,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorGreen(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorGreen_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1990,7 +982,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSchemeColor.class)

     public JAXBElement<CTComplementTransform> createCTSchemeColorComp(CTComplementTransform value) {

-        return new JAXBElement<CTComplementTransform>(_CTScRgbColorComp_QNAME, CTComplementTransform.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -1999,7 +991,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSchemeColor.class)

     public JAXBElement<CTPercentage> createCTSchemeColorBlueOff(CTPercentage value) {

-        return new JAXBElement<CTPercentage>(_CTScRgbColorBlueOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -2008,7 +1000,7 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSchemeColor.class)

     public JAXBElement<CTPositivePercentage> createCTSchemeColorHueMod(CTPositivePercentage value) {

-        return new JAXBElement<CTPositivePercentage>(_CTScRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSchemeColor.class, value);

     }

 

     /**

@@ -2017,7 +1009,1015 @@
      */

     @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSchemeColor.class)

     public JAXBElement<CTGrayscaleTransform> createCTSchemeColorGray(CTGrayscaleTransform value) {

-        return new JAXBElement<CTGrayscaleTransform>(_CTScRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSchemeColor.class, value);

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSchemeColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorAlpha(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorLum(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTScRgbColor.class)

+    public JAXBElement<CTGammaTransform> createCTScRgbColorGamma(CTGammaTransform value) {

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTScRgbColor.class)

+    public JAXBElement<CTInverseGammaTransform> createCTScRgbColorInvGamma(CTInverseGammaTransform value) {

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositivePercentage> createCTScRgbColorAlphaMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorRedOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTFixedPercentage> createCTScRgbColorAlphaOff(CTFixedPercentage value) {

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorGreenOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositiveFixedAngle> createCTScRgbColorHue(CTPositiveFixedAngle value) {

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorSatOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorGreenMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorSat(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorBlue(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorRed(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorSatMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorBlueMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTAngle> createCTScRgbColorHueOff(CTAngle value) {

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorShade(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorLumMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTScRgbColor.class)

+    public JAXBElement<CTInverseTransform> createCTScRgbColorInv(CTInverseTransform value) {

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorLumOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTScRgbColorTint(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorGreen(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTScRgbColor.class)

+    public JAXBElement<CTComplementTransform> createCTScRgbColorComp(CTComplementTransform value) {

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTScRgbColor.class)

+    public JAXBElement<CTPercentage> createCTScRgbColorBlueOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTScRgbColor.class)

+    public JAXBElement<CTPositivePercentage> createCTScRgbColorHueMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTScRgbColor.class)

+    public JAXBElement<CTGrayscaleTransform> createCTScRgbColorGray(CTGrayscaleTransform value) {

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTScRgbColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTSystemColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorAlpha(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorLum(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTSystemColor.class)

+    public JAXBElement<CTGammaTransform> createCTSystemColorGamma(CTGammaTransform value) {

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTSystemColor.class)

+    public JAXBElement<CTInverseGammaTransform> createCTSystemColorInvGamma(CTInverseGammaTransform value) {

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPositivePercentage> createCTSystemColorAlphaMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorRedOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTSystemColor.class)

+    public JAXBElement<CTFixedPercentage> createCTSystemColorAlphaOff(CTFixedPercentage value) {

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorGreenOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTSystemColor.class)

+    public JAXBElement<CTPositiveFixedAngle> createCTSystemColorHue(CTPositiveFixedAngle value) {

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorSatOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorGreenMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorSat(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorBlue(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorRed(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorSatMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorBlueMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTSystemColor.class)

+    public JAXBElement<CTAngle> createCTSystemColorHueOff(CTAngle value) {

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTSystemColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorShade(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorLumMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTSystemColor.class)

+    public JAXBElement<CTInverseTransform> createCTSystemColorInv(CTInverseTransform value) {

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorLumOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTSystemColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTSystemColorTint(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorGreen(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTSystemColor.class)

+    public JAXBElement<CTComplementTransform> createCTSystemColorComp(CTComplementTransform value) {

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTSystemColor.class)

+    public JAXBElement<CTPercentage> createCTSystemColorBlueOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTSystemColor.class)

+    public JAXBElement<CTPositivePercentage> createCTSystemColorHueMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTSystemColor.class)

+    public JAXBElement<CTGrayscaleTransform> createCTSystemColorGray(CTGrayscaleTransform value) {

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTSystemColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTHslColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorAlpha(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorLum(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTHslColor.class)

+    public JAXBElement<CTGammaTransform> createCTHslColorGamma(CTGammaTransform value) {

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTHslColor.class)

+    public JAXBElement<CTInverseGammaTransform> createCTHslColorInvGamma(CTInverseGammaTransform value) {

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTHslColor.class)

+    public JAXBElement<CTPositivePercentage> createCTHslColorAlphaMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorRedOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTHslColor.class)

+    public JAXBElement<CTFixedPercentage> createCTHslColorAlphaOff(CTFixedPercentage value) {

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorGreenOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTHslColor.class)

+    public JAXBElement<CTPositiveFixedAngle> createCTHslColorHue(CTPositiveFixedAngle value) {

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorSatOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorGreenMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorSat(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorBlue(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorRed(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorSatMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorBlueMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTHslColor.class)

+    public JAXBElement<CTAngle> createCTHslColorHueOff(CTAngle value) {

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTHslColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorShade(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorLumMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTHslColor.class)

+    public JAXBElement<CTInverseTransform> createCTHslColorInv(CTInverseTransform value) {

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorLumOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTHslColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTHslColorTint(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorGreen(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTHslColor.class)

+    public JAXBElement<CTComplementTransform> createCTHslColorComp(CTComplementTransform value) {

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTHslColor.class)

+    public JAXBElement<CTPercentage> createCTHslColorBlueOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTHslColor.class)

+    public JAXBElement<CTPositivePercentage> createCTHslColorHueMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTHslColor.class)

+    public JAXBElement<CTGrayscaleTransform> createCTHslColorGray(CTGrayscaleTransform value) {

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTHslColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alpha", scope = CTPresetColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorAlpha(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorAlpha_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lum", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorLum(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLum_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gamma", scope = CTPresetColor.class)

+    public JAXBElement<CTGammaTransform> createCTPresetColorGamma(CTGammaTransform value) {

+        return new JAXBElement<CTGammaTransform>(_CTSRgbColorGamma_QNAME, CTGammaTransform.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseGammaTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "invGamma", scope = CTPresetColor.class)

+    public JAXBElement<CTInverseGammaTransform> createCTPresetColorInvGamma(CTInverseGammaTransform value) {

+        return new JAXBElement<CTInverseGammaTransform>(_CTSRgbColorInvGamma_QNAME, CTInverseGammaTransform.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPositivePercentage> createCTPresetColorAlphaMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorAlphaMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redOff", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorRedOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "alphaOff", scope = CTPresetColor.class)

+    public JAXBElement<CTFixedPercentage> createCTPresetColorAlphaOff(CTFixedPercentage value) {

+        return new JAXBElement<CTFixedPercentage>(_CTSRgbColorAlphaOff_QNAME, CTFixedPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenOff", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorGreenOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hue", scope = CTPresetColor.class)

+    public JAXBElement<CTPositiveFixedAngle> createCTPresetColorHue(CTPositiveFixedAngle value) {

+        return new JAXBElement<CTPositiveFixedAngle>(_CTSRgbColorHue_QNAME, CTPositiveFixedAngle.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "redMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorRedMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRedMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satOff", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorSatOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "greenMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorGreenMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreenMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "sat", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorSat(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSat_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blue", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorBlue(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlue_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "red", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorRed(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorRed_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "satMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorSatMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorSatMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorBlueMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTAngle }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueOff", scope = CTPresetColor.class)

+    public JAXBElement<CTAngle> createCTPresetColorHueOff(CTAngle value) {

+        return new JAXBElement<CTAngle>(_CTSRgbColorHueOff_QNAME, CTAngle.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "shade", scope = CTPresetColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorShade(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorShade_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorLumMod(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumMod_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTInverseTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "inv", scope = CTPresetColor.class)

+    public JAXBElement<CTInverseTransform> createCTPresetColorInv(CTInverseTransform value) {

+        return new JAXBElement<CTInverseTransform>(_CTSRgbColorInv_QNAME, CTInverseTransform.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "lumOff", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorLumOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorLumOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositiveFixedPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "tint", scope = CTPresetColor.class)

+    public JAXBElement<CTPositiveFixedPercentage> createCTPresetColorTint(CTPositiveFixedPercentage value) {

+        return new JAXBElement<CTPositiveFixedPercentage>(_CTSRgbColorTint_QNAME, CTPositiveFixedPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "green", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorGreen(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorGreen_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTComplementTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "comp", scope = CTPresetColor.class)

+    public JAXBElement<CTComplementTransform> createCTPresetColorComp(CTComplementTransform value) {

+        return new JAXBElement<CTComplementTransform>(_CTSRgbColorComp_QNAME, CTComplementTransform.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "blueOff", scope = CTPresetColor.class)

+    public JAXBElement<CTPercentage> createCTPresetColorBlueOff(CTPercentage value) {

+        return new JAXBElement<CTPercentage>(_CTSRgbColorBlueOff_QNAME, CTPercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTPositivePercentage }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "hueMod", scope = CTPresetColor.class)

+    public JAXBElement<CTPositivePercentage> createCTPresetColorHueMod(CTPositivePercentage value) {

+        return new JAXBElement<CTPositivePercentage>(_CTSRgbColorHueMod_QNAME, CTPositivePercentage.class, CTPresetColor.class, value);

+    }

+

+    /**

+     * Create an instance of {@link JAXBElement }{@code <}{@link CTGrayscaleTransform }{@code >}}

+     * 

+     */

+    @XmlElementDecl(namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", name = "gray", scope = CTPresetColor.class)

+    public JAXBElement<CTGrayscaleTransform> createCTPresetColorGray(CTGrayscaleTransform value) {

+        return new JAXBElement<CTGrayscaleTransform>(_CTSRgbColorGray_QNAME, CTGrayscaleTransform.class, CTPresetColor.class, value);

     }

 

 }

diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java b/src/java/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java
rename to src/java/org/apache/poi/sl/draw/binding/STBlackWhiteMode.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STPathFillMode.java b/src/java/org/apache/poi/sl/draw/binding/STPathFillMode.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STPathFillMode.java
rename to src/java/org/apache/poi/sl/draw/binding/STPathFillMode.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STPresetColorVal.java b/src/java/org/apache/poi/sl/draw/binding/STPresetColorVal.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STPresetColorVal.java
rename to src/java/org/apache/poi/sl/draw/binding/STPresetColorVal.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STRectAlignment.java b/src/java/org/apache/poi/sl/draw/binding/STRectAlignment.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STRectAlignment.java
rename to src/java/org/apache/poi/sl/draw/binding/STRectAlignment.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STSchemeColorVal.java b/src/java/org/apache/poi/sl/draw/binding/STSchemeColorVal.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STSchemeColorVal.java
rename to src/java/org/apache/poi/sl/draw/binding/STSchemeColorVal.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STShapeType.java b/src/java/org/apache/poi/sl/draw/binding/STShapeType.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STShapeType.java
rename to src/java/org/apache/poi/sl/draw/binding/STShapeType.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/binding/STTextShapeType.java b/src/java/org/apache/poi/sl/draw/binding/STTextShapeType.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/binding/STTextShapeType.java
rename to src/java/org/apache/poi/sl/draw/binding/STTextShapeType.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/AbsExpression.java b/src/java/org/apache/poi/sl/draw/geom/AbsExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/AbsExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/AbsExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/AddDivideExpression.java b/src/java/org/apache/poi/sl/draw/geom/AddDivideExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/AddDivideExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/AddDivideExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/AddSubtractExpression.java b/src/java/org/apache/poi/sl/draw/geom/AddSubtractExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/AddSubtractExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/AddSubtractExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/AdjustValue.java b/src/java/org/apache/poi/sl/draw/geom/AdjustValue.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/AdjustValue.java
rename to src/java/org/apache/poi/sl/draw/geom/AdjustValue.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/ArcTanExpression.java b/src/java/org/apache/poi/sl/draw/geom/ArcTanExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/ArcTanExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/ArcTanExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/ArcToCommand.java b/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/ArcToCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/ClosePathCommand.java b/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/ClosePathCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Context.java b/src/java/org/apache/poi/sl/draw/geom/Context.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Context.java
rename to src/java/org/apache/poi/sl/draw/geom/Context.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/CosExpression.java b/src/java/org/apache/poi/sl/draw/geom/CosExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/CosExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/CosExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java b/src/java/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/CosineArcTanExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/CurveToCommand.java b/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/CurveToCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/CustomGeometry.java b/src/java/org/apache/poi/sl/draw/geom/CustomGeometry.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/CustomGeometry.java
rename to src/java/org/apache/poi/sl/draw/geom/CustomGeometry.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Expression.java b/src/java/org/apache/poi/sl/draw/geom/Expression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Expression.java
rename to src/java/org/apache/poi/sl/draw/geom/Expression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/ExpressionParser.java b/src/java/org/apache/poi/sl/draw/geom/ExpressionParser.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/ExpressionParser.java
rename to src/java/org/apache/poi/sl/draw/geom/ExpressionParser.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Formula.java b/src/java/org/apache/poi/sl/draw/geom/Formula.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Formula.java
rename to src/java/org/apache/poi/sl/draw/geom/Formula.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Guide.java b/src/java/org/apache/poi/sl/draw/geom/Guide.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Guide.java
rename to src/java/org/apache/poi/sl/draw/geom/Guide.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/IAdjustableShape.java b/src/java/org/apache/poi/sl/draw/geom/IAdjustableShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/IAdjustableShape.java
rename to src/java/org/apache/poi/sl/draw/geom/IAdjustableShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/IfElseExpression.java b/src/java/org/apache/poi/sl/draw/geom/IfElseExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/IfElseExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/IfElseExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/LineToCommand.java b/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/LineToCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/LineToCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/LiteralValueExpression.java b/src/java/org/apache/poi/sl/draw/geom/LiteralValueExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/LiteralValueExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/LiteralValueExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/MaxExpression.java b/src/java/org/apache/poi/sl/draw/geom/MaxExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/MaxExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/MaxExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/MinExpression.java b/src/java/org/apache/poi/sl/draw/geom/MinExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/MinExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/MinExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/ModExpression.java b/src/java/org/apache/poi/sl/draw/geom/ModExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/ModExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/ModExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/MoveToCommand.java b/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/MoveToCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java b/src/java/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/MultiplyDivideExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Outline.java b/src/java/org/apache/poi/sl/draw/geom/Outline.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Outline.java
rename to src/java/org/apache/poi/sl/draw/geom/Outline.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/Path.java b/src/java/org/apache/poi/sl/draw/geom/Path.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/Path.java
rename to src/java/org/apache/poi/sl/draw/geom/Path.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/PathCommand.java b/src/java/org/apache/poi/sl/draw/geom/PathCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/PathCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/PathCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/PinExpression.java b/src/java/org/apache/poi/sl/draw/geom/PinExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/PinExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/PinExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/PresetGeometries.java b/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/PresetGeometries.java
rename to src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/QuadToCommand.java b/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/QuadToCommand.java
rename to src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/SinArcTanExpression.java b/src/java/org/apache/poi/sl/draw/geom/SinArcTanExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/SinArcTanExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/SinArcTanExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/SinExpression.java b/src/java/org/apache/poi/sl/draw/geom/SinExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/SinExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/SinExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/SqrtExpression.java b/src/java/org/apache/poi/sl/draw/geom/SqrtExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/SqrtExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/SqrtExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/geom/TanExpression.java b/src/java/org/apache/poi/sl/draw/geom/TanExpression.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/draw/geom/TanExpression.java
rename to src/java/org/apache/poi/sl/draw/geom/TanExpression.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoNumberingScheme.java b/src/java/org/apache/poi/sl/usermodel/AutoNumberingScheme.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/AutoNumberingScheme.java
rename to src/java/org/apache/poi/sl/usermodel/AutoNumberingScheme.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java b/src/java/org/apache/poi/sl/usermodel/AutoShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java
rename to src/java/org/apache/poi/sl/usermodel/AutoShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java b/src/java/org/apache/poi/sl/usermodel/Background.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java
rename to src/java/org/apache/poi/sl/usermodel/Background.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ColorStyle.java b/src/java/org/apache/poi/sl/usermodel/ColorStyle.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/ColorStyle.java
rename to src/java/org/apache/poi/sl/usermodel/ColorStyle.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ConnectorShape.java b/src/java/org/apache/poi/sl/usermodel/ConnectorShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/ConnectorShape.java
rename to src/java/org/apache/poi/sl/usermodel/ConnectorShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/FillStyle.java b/src/java/org/apache/poi/sl/usermodel/FillStyle.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/FillStyle.java
rename to src/java/org/apache/poi/sl/usermodel/FillStyle.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/FontCollection.java b/src/java/org/apache/poi/sl/usermodel/FontCollection.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/FontCollection.java
rename to src/java/org/apache/poi/sl/usermodel/FontCollection.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java b/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java
rename to src/java/org/apache/poi/sl/usermodel/FreeformShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/GroupShape.java b/src/java/org/apache/poi/sl/usermodel/GroupShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/GroupShape.java
rename to src/java/org/apache/poi/sl/usermodel/GroupShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Hyperlink.java b/src/java/org/apache/poi/sl/usermodel/Hyperlink.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Hyperlink.java
rename to src/java/org/apache/poi/sl/usermodel/Hyperlink.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Insets2D.java b/src/java/org/apache/poi/sl/usermodel/Insets2D.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Insets2D.java
rename to src/java/org/apache/poi/sl/usermodel/Insets2D.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Line.java b/src/java/org/apache/poi/sl/usermodel/Line.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Line.java
rename to src/java/org/apache/poi/sl/usermodel/Line.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/LineDecoration.java b/src/java/org/apache/poi/sl/usermodel/LineDecoration.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/LineDecoration.java
rename to src/java/org/apache/poi/sl/usermodel/LineDecoration.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java b/src/java/org/apache/poi/sl/usermodel/MasterSheet.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java
rename to src/java/org/apache/poi/sl/usermodel/MasterSheet.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java b/src/java/org/apache/poi/sl/usermodel/Notes.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java
rename to src/java/org/apache/poi/sl/usermodel/Notes.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java b/src/java/org/apache/poi/sl/usermodel/PaintStyle.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java
rename to src/java/org/apache/poi/sl/usermodel/PaintStyle.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java b/src/java/org/apache/poi/sl/usermodel/PictureData.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java
rename to src/java/org/apache/poi/sl/usermodel/PictureData.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java b/src/java/org/apache/poi/sl/usermodel/PictureShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java
rename to src/java/org/apache/poi/sl/usermodel/PictureShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java b/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java
rename to src/java/org/apache/poi/sl/usermodel/PlaceableShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Resources.java b/src/java/org/apache/poi/sl/usermodel/Resources.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Resources.java
rename to src/java/org/apache/poi/sl/usermodel/Resources.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java b/src/java/org/apache/poi/sl/usermodel/Shadow.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java
rename to src/java/org/apache/poi/sl/usermodel/Shadow.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java b/src/java/org/apache/poi/sl/usermodel/Shape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java
rename to src/java/org/apache/poi/sl/usermodel/Shape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java b/src/java/org/apache/poi/sl/usermodel/ShapeContainer.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java
rename to src/java/org/apache/poi/sl/usermodel/ShapeContainer.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeType.java b/src/java/org/apache/poi/sl/usermodel/ShapeType.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeType.java
rename to src/java/org/apache/poi/sl/usermodel/ShapeType.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java b/src/java/org/apache/poi/sl/usermodel/Sheet.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java
rename to src/java/org/apache/poi/sl/usermodel/Sheet.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java b/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java
rename to src/java/org/apache/poi/sl/usermodel/SimpleShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java b/src/java/org/apache/poi/sl/usermodel/Slide.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java
rename to src/java/org/apache/poi/sl/usermodel/Slide.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/SlideShow.java b/src/java/org/apache/poi/sl/usermodel/SlideShow.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/SlideShow.java
rename to src/java/org/apache/poi/sl/usermodel/SlideShow.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/StrokeStyle.java b/src/java/org/apache/poi/sl/usermodel/StrokeStyle.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/StrokeStyle.java
rename to src/java/org/apache/poi/sl/usermodel/StrokeStyle.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/java/org/apache/poi/sl/usermodel/TableShape.java
similarity index 94%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
rename to src/java/org/apache/poi/sl/usermodel/TableShape.java
index 48744ec..4fda40f 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/TableShape.java
@@ -17,6 +17,6 @@
 

 package org.apache.poi.sl.usermodel;

 

-public interface TableShape extends Shape {

+public interface TableShape extends Shape, PlaceableShape {

     // to be defined ...

 }

diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java b/src/java/org/apache/poi/sl/usermodel/TextBox.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java
rename to src/java/org/apache/poi/sl/usermodel/TextBox.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
rename to src/java/org/apache/poi/sl/usermodel/TextParagraph.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextRun.java b/src/java/org/apache/poi/sl/usermodel/TextRun.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/TextRun.java
rename to src/java/org/apache/poi/sl/usermodel/TextRun.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java b/src/java/org/apache/poi/sl/usermodel/TextShape.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java
rename to src/java/org/apache/poi/sl/usermodel/TextShape.java
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/VerticalAlignment.java b/src/java/org/apache/poi/sl/usermodel/VerticalAlignment.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/sl/usermodel/VerticalAlignment.java
rename to src/java/org/apache/poi/sl/usermodel/VerticalAlignment.java
diff --git a/src/java/org/apache/poi/ss/formula/FormulaParser.java b/src/java/org/apache/poi/ss/formula/FormulaParser.java
index 72ed008..5124a44 100644
--- a/src/java/org/apache/poi/ss/formula/FormulaParser.java
+++ b/src/java/org/apache/poi/ss/formula/FormulaParser.java
@@ -617,16 +617,16 @@
 		return new ParseNode(ptg);
 	}
 
-	private static AreaReference createAreaRef(SimpleRangePart part1, SimpleRangePart part2) {
+	private AreaReference createAreaRef(SimpleRangePart part1, SimpleRangePart part2) {
 		if (!part1.isCompatibleForArea(part2)) {
 			throw new FormulaParseException("has incompatible parts: '"
 					+ part1.getRep() + "' and '" + part2.getRep() + "'.");
 		}
 		if (part1.isRow()) {
-			return AreaReference.getWholeRow(part1.getRep(), part2.getRep());
+			return AreaReference.getWholeRow(_ssVersion, part1.getRep(), part2.getRep());
 		}
 		if (part1.isColumn()) {
-			return AreaReference.getWholeColumn(part1.getRep(), part2.getRep());
+			return AreaReference.getWholeColumn(_ssVersion, part1.getRep(), part2.getRep());
 		}
 		return new AreaReference(part1.getCellReference(), part2.getCellReference());
 	}
diff --git a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java
index 5ba8947..cf88b37 100644
--- a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java
+++ b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java
@@ -27,8 +27,8 @@
 import org.apache.poi.ss.formula.functions.*;
 
 /**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- * @author Johan Karlsteen - added Intercept and Slope
+ * Mappings from the Excel functions to our evaluation implementations
+ *  (where avilable)
  */
 public final class FunctionEval {
     /**
@@ -99,7 +99,7 @@
         retval[39] = NumericFunction.MOD;
 
         retval[43] = new DStarRunner(new DMin());
-        
+
         retval[46] = AggregateFunction.VAR;
         retval[48] = TextFunction.TEXT;
 
@@ -154,6 +154,7 @@
 
         retval[124] = TextFunction.FIND;
 
+        retval[126] = LogicalFunction.ISERR;
         retval[127] = LogicalFunction.ISTEXT;
         retval[128] = LogicalFunction.ISNUMBER;
         retval[129] = LogicalFunction.ISBLANK;
@@ -161,7 +162,7 @@
 
         retval[FunctionID.INDIRECT] = null; // Indirect.evaluate has different signature
 
-        retval[162] = TextFunction.CLEAN;  //Aniket Banerjee    
+        retval[162] = TextFunction.CLEAN;    
         retval[167] = new IPMT();
         retval[168] = new PPMT();
         retval[169] = new Counta();
@@ -177,7 +178,7 @@
         retval[212] = NumericFunction.ROUNDUP;
         retval[213] = NumericFunction.ROUNDDOWN;
         retval[216] = new Rank();
-        retval[219] = new Address();  //Aniket Banerjee
+        retval[219] = new Address();
         retval[220] = new Days360();
         retval[221] = new Today();
 
@@ -290,7 +291,7 @@
                 throw new IllegalArgumentException(name + " is a function from the Excel Analysis Toolpack. " +
                         "Use AnalysisToolpack.registerFunction(String name, FreeRefFunction func) instead.");
             }
-            
+
             throw new IllegalArgumentException("Unknown function: " + name);
         }
 
diff --git a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
index 8e0ea3b..af4cb81 100644
--- a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
+++ b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
@@ -57,7 +57,7 @@
 	 */
 	public static ValueEval getSingleValue(ValueEval arg, int srcCellRow, int srcCellCol)
 			throws EvaluationException {
-		ValueEval result;
+		final ValueEval result;
 		if (arg instanceof RefEval) {
 			result = chooseSingleElementFromRef((RefEval) arg);
 		} else if (arg instanceof AreaEval) {
diff --git a/src/java/org/apache/poi/ss/formula/functions/Countif.java b/src/java/org/apache/poi/ss/formula/functions/Countif.java
index 6f27fdf..9023815 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Countif.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Countif.java
@@ -30,7 +30,7 @@
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate;
-import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.ss.usermodel.FormulaError;
 
 /**
  * Implementation for the function COUNTIF
@@ -254,6 +254,7 @@
 					// boolean values when the target(x) is a string
 					return false;
 				}
+				@SuppressWarnings("unused")
 				StringEval se = (StringEval)x;
 				Boolean val = parseBoolean(se.getStringValue());
 				if(val == null) {
@@ -286,7 +287,7 @@
 			return evaluate(testValue - _value);
 		}
 	}
-	private static final class ErrorMatcher extends MatcherBase {
+	public static final class ErrorMatcher extends MatcherBase {
 
 		private final int _value;
 
@@ -296,7 +297,7 @@
 		}
 		@Override
 		protected String getValueText() {
-			return ErrorConstants.getText(_value);
+			return FormulaError.forInt(_value).getString();
 		}
 
 		public boolean matches(ValueEval x) {
@@ -306,6 +307,10 @@
 			}
 			return false;
 		}
+		
+		public int getValue() {
+		    return _value;
+		}
 	}
 	public static final class StringMatcher extends MatcherBase {
 
@@ -486,7 +491,7 @@
 	 */
 	private static ValueEval evaluateCriteriaArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) {
 		try {
-			return OperandResolver.getSingleValue(arg, srcRowIndex, (short)srcColumnIndex);
+			return OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
 		} catch (EvaluationException e) {
 			return e.getErrorEval();
 		}
diff --git a/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java b/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
index ef18dab..c4b3e67 100644
--- a/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
@@ -90,6 +90,27 @@
 		}
 	};
 
+    /**
+     * Implementation of Excel <tt>ISERR()</tt> function.<p/>
+     *
+     * <b>Syntax</b>:<br/>
+     * <b>ISERR</b>(<b>value</b>)<p/>
+     *
+     * <b>value</b>  The value to be tested<p/>
+     *
+     * Returns the logical value <tt>TRUE</tt> if value refers to any error value except
+     * <tt>'#N/A'</tt>; otherwise, it returns <tt>FALSE</tt>.
+     */
+    public static final Function ISERR = new LogicalFunction() {
+        @Override
+        protected boolean evaluate(ValueEval arg) {
+            if (arg instanceof ErrorEval) {
+                return arg != ErrorEval.NA;
+            }
+            return false;
+        }
+    };
+
 	/**
 	 * Implementation for Excel ISNA() function.<p/>
 	 *
diff --git a/src/java/org/apache/poi/ss/formula/functions/Sumif.java b/src/java/org/apache/poi/ss/formula/functions/Sumif.java
index ef381ad..977647f 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Sumif.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Sumif.java
@@ -69,6 +69,12 @@
 			AreaEval aeSum) {
 		// TODO - junit to prove last arg must be srcColumnIndex and not srcRowIndex
 		I_MatchPredicate mp = Countif.createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
+		
+		// handle empty cells
+		if(mp == null) {
+		    return NumberEval.ZERO;
+		}
+
 		double result = sumMatchingCells(aeRange, mp, aeSum);
 		return new NumberEval(result);
 	}
diff --git a/src/java/org/apache/poi/ss/formula/functions/Sumifs.java b/src/java/org/apache/poi/ss/formula/functions/Sumifs.java
index 63d3543..ebdddb6 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Sumifs.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Sumifs.java
@@ -20,8 +20,14 @@
 package org.apache.poi.ss.formula.functions;
 
 import org.apache.poi.ss.formula.OperationEvaluationContext;
-import org.apache.poi.ss.formula.eval.*;
+import org.apache.poi.ss.formula.eval.AreaEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.EvaluationException;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.RefEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate;
+import org.apache.poi.ss.formula.functions.Countif.ErrorMatcher;
 
 /**
  * Implementation for the Excel function SUMIFS<p>
@@ -48,6 +54,7 @@
     public static final FreeRefFunction instance = new Sumifs();
 
 	public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+	    // need at least 3 arguments and need to have an odd number of arguments (sum-range plus x*(criteria_range, criteria))
         if(args.length < 3 || args.length % 2 == 0) {
             return ErrorEval.VALUE_INVALID;
         }
@@ -60,10 +67,12 @@
             I_MatchPredicate[] mp = new I_MatchPredicate[ae.length];
             for(int i = 1, k=0; i < args.length; i += 2, k++){
                 ae[k] = convertRangeArg(args[i]);
+                
                 mp[k] = Countif.createCriteriaPredicate(args[i+1], ec.getRowIndex(), ec.getColumnIndex());
             }
 
             validateCriteriaRanges(ae, sumRange);
+            validateCriteria(mp);
 
             double result = sumMatchingCells(ae, mp, sumRange);
             return new NumberEval(result);
@@ -76,7 +85,7 @@
      * Verify that each <code>criteriaRanges</code> argument contains the same number of rows and columns
      * as the <code>sumRange</code> argument
      *
-     * @throws EvaluationException if
+     * @throws EvaluationException if the ranges do not match.
      */
     private void validateCriteriaRanges(AreaEval[] criteriaRanges, AreaEval sumRange) throws EvaluationException {
         for(AreaEval r : criteriaRanges){
@@ -88,6 +97,22 @@
     }
 
     /**
+     * Verify that each <code>criteria</code> predicate is valid, i.e. not an error
+     *
+     * @throws EvaluationException if there are criteria which resulted in Errors.
+     */
+    private void validateCriteria(I_MatchPredicate[] criteria) throws EvaluationException {
+        for(I_MatchPredicate predicate : criteria) {
+            
+            // check for errors in predicate and return immediately using this error code
+            if(predicate instanceof ErrorMatcher) {
+                throw new EvaluationException(ErrorEval.valueOf(((ErrorMatcher)predicate).getValue()));
+            }
+        }
+    }
+
+
+    /**
      *
      * @param ranges  criteria ranges, each range must be of the same dimensions as <code>aeSum</code>
      * @param predicates  array of predicates, a predicate for each value in <code>ranges</code>
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
index e27ccdd..665ac98 100644
--- a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
@@ -31,7 +31,7 @@
  * <p>This is XSSF only, as it stores the sheet / book references
  *  in String form. The HSSF equivalent using indexes is {@link Area3DPtg}</p>
  */
-public final class Area3DPxg extends AreaPtgBase implements Pxg {
+public final class Area3DPxg extends AreaPtgBase implements Pxg3D {
     private int externalWorkbookNumber = -1;
     private String firstSheetName;
     private String lastSheetName;
diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java b/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java
index 5b77b09..96eda87 100644
--- a/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.BitField;
@@ -256,7 +257,7 @@
 		CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative());
 		CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative());
 
-		if(AreaReference.isWholeColumnReference(topLeft, botRight)) {
+		if(AreaReference.isWholeColumnReference(SpreadsheetVersion.EXCEL97, topLeft, botRight)) {
 			return (new AreaReference(topLeft, botRight)).formatAsString();
 		}
 		return topLeft.formatAsString() + ":" + botRight.formatAsString();
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java
similarity index 76%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java
index 48744ec..49083fe 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/Pxg3D.java
@@ -1,22 +1,27 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

-

-       http://www.apache.org/licenses/LICENSE-2.0

-

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

-

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * An XSSF only special kind of Ptg, which stores a range of 
+ *  sheet / book references in string form.
+ */
+public interface Pxg3D extends Pxg {
+    public String getLastSheetName();
+    public void setLastSheetName(String sheetName);
+}
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
index 41039cd..3b78c5a 100644
--- a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
@@ -31,7 +31,7 @@
  * <p>This is XSSF only, as it stores the sheet / book references
  *  in String form. The HSSF equivalent using indexes is {@link Ref3DPtg}</p>
  */
-public final class Ref3DPxg extends RefPtgBase implements Pxg {
+public final class Ref3DPxg extends RefPtgBase implements Pxg3D {
     private int externalWorkbookNumber = -1;
     private String firstSheetName;
     private String lastSheetName;
diff --git a/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java b/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java
index c15dc26..165cf05 100644
--- a/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java
+++ b/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java
@@ -20,8 +20,8 @@
 package org.apache.poi.ss.usermodel;

 

 /**

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

+ * High level representation for Border Formatting component

+ * of Conditional Formatting settings

  */

 public interface BorderFormatting {

     /** No border */

@@ -64,14 +64,19 @@
     short getBorderTop();

 

     short getBottomBorderColor();

+    Color getBottomBorderColorColor();

 

     short getDiagonalBorderColor();

+    Color getDiagonalBorderColorColor();

 

     short getLeftBorderColor();

+    Color getLeftBorderColorColor();

 

     short getRightBorderColor();

+    Color getRightBorderColorColor();

 

     short getTopBorderColor();

+    Color getTopBorderColorColor();

 

     void setBorderBottom(short border);

 

@@ -104,12 +109,17 @@
     void setBorderTop(short border);

 

     void setBottomBorderColor(short color);

+    void setBottomBorderColor(Color color);

 

     void setDiagonalBorderColor(short color);

+    void setDiagonalBorderColor(Color color);

 

     void setLeftBorderColor(short color);

+    void setLeftBorderColor(Color color);

 

     void setRightBorderColor(short color);

+    void setRightBorderColor(Color color);

 

     void setTopBorderColor(short color);

+    void setTopBorderColor(Color color);

 }

diff --git a/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java b/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java
new file mode 100644
index 0000000..4d6f58b
--- /dev/null
+++ b/src/java/org/apache/poi/ss/usermodel/ColorScaleFormatting.java
@@ -0,0 +1,66 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.ss.usermodel;

+

+import org.apache.poi.hssf.record.cf.Threshold;

+

+/**

+ * High level representation for the Color Scale / Colour Scale /

+ *  Color Gradient Formatting component of Conditional Formatting settings

+ */

+public interface ColorScaleFormatting {

+    /**

+     * How many control points should be used to map 

+     *  the colours? Normally 2 or 3

+     */

+    int getNumControlPoints();

+    /**

+     * Sets the number of control points to use to map

+     *  the colours. Should normally be 2 or 3.

+     * <p>After updating, you need to ensure that the

+     *  {@link Threshold} count and Color count match

+     */

+    void setNumControlPoints(int num);

+

+    /**

+     * Gets the list of colours that are interpolated

+     *  between.

+     */

+    Color[] getColors();

+    /**

+     * Sets the list of colours that are interpolated

+     *  between. The number must match {@link #getNumControlPoints()}

+     */

+    void setColors(Color[] colors);

+    

+    /**

+     * Gets the list of thresholds

+     */

+    ConditionalFormattingThreshold[] getThresholds();

+    /**

+     * Sets the of thresholds. The number must match

+     *  {@link #getNumControlPoints()}

+     */

+    void setThresholds(ConditionalFormattingThreshold[] thresholds);

+    /**

+     * Creates a new, empty Threshold

+     */

+    ConditionalFormattingThreshold createThreshold();

+}

diff --git a/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java b/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java
index 7e29cbf..7eee789 100644
--- a/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java
+++ b/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java
@@ -24,9 +24,6 @@
  * <p>

  * For example, "highlight cells that begin with "M2" and contain "Mountain Gear".

  * </p>

- *

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

  */

 public final class ComparisonOperator {

     public static final byte NO_COMPARISON = 0;

diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionType.java b/src/java/org/apache/poi/ss/usermodel/ConditionType.java
new file mode 100644
index 0000000..8bd6141
--- /dev/null
+++ b/src/java/org/apache/poi/ss/usermodel/ConditionType.java
@@ -0,0 +1,92 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.ss.usermodel;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * Represents a type of a conditional formatting rule

+ */

+public class ConditionType {

+    private static Map<Integer,ConditionType> lookup = new HashMap<Integer, ConditionType>();

+    

+    /**

+     * This conditional formatting rule compares a cell value

+     * to a formula calculated result, using an operator

+     */

+    public static final ConditionType CELL_VALUE_IS = 

+            new ConditionType(1, "cellIs");

+

+    /**

+     * This conditional formatting rule contains a formula to evaluate.

+     * When the formula result is true, the cell is highlighted.

+     */

+    public static final ConditionType FORMULA = 

+            new ConditionType(2, "expression");

+    

+    /**

+     * This conditional formatting rule contains a color scale,

+     * with the cell background set according to a gradient.

+     */

+    public static final ConditionType COLOR_SCALE = 

+            new ConditionType(3, "colorScale");

+    

+    /**

+     * This conditional formatting rule sets a data bar, with the

+     *  cell populated with bars based on their values

+     */

+    public static final ConditionType DATA_BAR = 

+            new ConditionType(4, "dataBar");

+    

+    /**

+     * This conditional formatting rule that files the values

+     */

+    public static final ConditionType FILTER = 

+            new ConditionType(5, null);

+    

+    /**

+     * This conditional formatting rule sets a data bar, with the

+     *  cell populated with bars based on their values

+     */

+    public static final ConditionType ICON_SET = 

+            new ConditionType(6, "iconSet");

+    

+    

+    public final byte id;

+    public final String type;

+

+    public String toString() {

+        return id + " - " + type;

+    }

+    

+    

+    public static ConditionType forId(byte id) {

+        return forId((int)id);

+    }

+    public static ConditionType forId(int id) {

+        return lookup.get(id);

+    }

+        

+    private ConditionType(int id, String type) {

+        this.id = (byte)id; this.type = type;

+        lookup.put(id, this);

+    }

+}

diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java
index 3344963..f6e8ff4 100644
--- a/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java
+++ b/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java
@@ -72,9 +72,6 @@
  * // Apply Conditional Formatting rule defined above to the regions

  * sheet.addConditionalFormatting(regions, rule);

  * </PRE>

- *

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

  */

 public interface ConditionalFormatting {

 

@@ -85,17 +82,18 @@
 

     /**

      * Replaces an existing Conditional Formatting rule at position idx.

-     * Excel allows to create up to 3 Conditional Formatting rules.

+     * Excel pre-2007 allows to create up to 3 Conditional Formatting rules,

+     *  2007 and later allow unlimited numbers.

      * This method can be useful to modify existing  Conditional Formatting rules.

      *

-     * @param idx position of the rule. Should be between 0 and 2.

+     * @param idx position of the rule. Should be between 0 and 2 for Excel before 2007, otherwise 0+.

      * @param cfRule - Conditional Formatting rule

      */

     void setRule(int idx, ConditionalFormattingRule cfRule);

 

     /**

      * Add a Conditional Formatting rule.

-     * Excel allows to create up to 3 Conditional Formatting rules.

+     * Excel pre-2007 allows to create up to 3 Conditional Formatting rules.

      *

      * @param cfRule - Conditional Formatting rule

      */

@@ -110,6 +108,4 @@
      * @return number of Conditional Formatting rules.

      */

     int getNumberOfRules();

-

-

 }

diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java
index 1c63f19..5fb3151 100644
--- a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java
+++ b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java
@@ -19,24 +19,25 @@
 

 package org.apache.poi.ss.usermodel;

 

+import static org.apache.poi.ss.usermodel.ConditionType.*;

+

 /**

  * Represents a description of a conditional formatting rule

- *

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

  */

 public interface ConditionalFormattingRule {

     /**

      * This conditional formatting rule compares a cell value

      * to a formula calculated result, using an operator

+     * @deprecated Use {@link ConditionType#CELL_VALUE_IS}

      */

-    public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;

+    public static final byte CONDITION_TYPE_CELL_VALUE_IS = CELL_VALUE_IS.id;

 

     /**

      *  This conditional formatting rule contains a formula to evaluate.

      *  When the formula result is true, the cell is highlighted.

+     * @deprecated Use {@link ConditionType#FORMULA}

      */

-    public static final byte CONDITION_TYPE_FORMULA = 2;

+    public static final byte CONDITION_TYPE_FORMULA = FORMULA.id;

 

     /**

      * Create a new border formatting structure if it does not exist,

@@ -73,19 +74,32 @@
     PatternFormatting createPatternFormatting();

 

     /**

-     * @return - pattern formatting object  if defined,  <code>null</code> otherwise

+     * @return - pattern formatting object if defined, <code>null</code> otherwise

      */

     PatternFormatting getPatternFormatting();

 

     /**

+     * @return - icon / multi-state formatting object if defined, <code>null</code> otherwise

+     */

+    IconMultiStateFormatting getMultiStateFormatting();

+    

+    /**

      * Type of conditional formatting rule.

      * <p>

-     * MUST be either {@link #CONDITION_TYPE_CELL_VALUE_IS} or  {@link #CONDITION_TYPE_FORMULA}

+     * MUST be one of the IDs of a {@link ConditionType}

      * </p>

      *

      * @return the type of condition

+     * @deprecated Use {@link #getConditionTypeType()}

      */

     byte getConditionType();

+    

+    /**

+     * Type of conditional formatting rule.

+     *

+     * @return the type of condition

+     */

+    ConditionType getConditionTypeType();

 

     /**

      * The comparison function used when the type of conditional formatting is set to

diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java
new file mode 100644
index 0000000..8f2ecaf
--- /dev/null
+++ b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingThreshold.java
@@ -0,0 +1,110 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.ss.usermodel;

+

+

+/**

+ * The Threshold / CFVO / Conditional Formatting Value Object.

+ * <p>This defines how to calculate the ranges for a conditional

+ *  formatting rule, eg which values get a Green Traffic Light

+ *  icon and which Yellow or Red.</p>

+ */

+public interface ConditionalFormattingThreshold {

+    public enum RangeType {

+        /** Number / Parameter */

+        NUMBER(1, "num"),

+        /** The minimum value from the range */

+        MIN(2, "min"),

+        /** The maximum value from the range */

+        MAX(3, "max"),

+        /** Percent of the way from the mi to the max value in the range */

+        PERCENT(4, "percent"),

+        /** The minimum value of the cell that is in X percentile of the range */

+        PERCENTILE(5, "percentile"),

+        UNALLOCATED(6, null),

+        /** Formula result */

+        FORMULA(7, "formula");

+        

+        /** Numeric ID of the type */

+        public int id;

+        /** Name (system) of the type */

+        public final String name;

+        

+        public String toString() {

+            return id + " - " + name;

+        }

+        

+        public static RangeType byId(int id) {

+            return values()[id-1]; // 1-based IDs

+        }

+        public static RangeType byName(String name) {

+            for (RangeType t : values()) {

+                if (t.name.equals(name)) return t;

+            }

+            return null;

+        }

+        

+        private RangeType(int id, String name) {

+            this.id = id; this.name = name;

+        }

+    }

+    

+    /**

+     * Get the Range Type used

+     */

+    RangeType getRangeType();

+    

+    /**

+     * Changes the Range Type used

+     * 

+     * <p>If you change the range type, you need to

+     *  ensure that the Formula and Value parameters

+     *  are compatible with it before saving</p>

+     */

+    void setRangeType(RangeType type);

+    

+    /**

+     * Formula to use to calculate the threshold,

+     *  or <code>null</code> if no formula 

+     */

+    String getFormula();

+

+    /**

+     * Sets the formula used to calculate the threshold,

+     *  or unsets it if <code>null</code> is given.

+     */

+    void setFormula(String formula);

+    

+    /**

+     * Gets the value used for the threshold, or 

+     *  <code>null</code> if there isn't one.

+     */

+    Double getValue();

+    

+    /**

+     * Sets the value used for the threshold. 

+     * <p>If the type is {@link RangeType#PERCENT} or 

+     *  {@link RangeType#PERCENTILE} it must be between 0 and 100.

+     * <p>If the type is {@link RangeType#MIN} or {@link RangeType#MAX}

+     *  or {@link RangeType#FORMULA} it shouldn't be set.

+     * <p>Use <code>null</code> to unset

+     */

+    void setValue(Double value);

+}

diff --git a/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java b/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java
new file mode 100644
index 0000000..df9a0fe
--- /dev/null
+++ b/src/java/org/apache/poi/ss/usermodel/DataBarFormatting.java
@@ -0,0 +1,72 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.ss.usermodel;

+

+/**

+ * High level representation for the DataBar Formatting 

+ *  component of Conditional Formatting settings

+ */

+public interface DataBarFormatting {

+    /**

+     * Is the bar drawn from Left-to-Right, or from

+     *  Right-to-Left

+     */

+    boolean isLeftToRight();

+    /**

+     * Control if the bar is drawn from Left-to-Right,

+     *  or from Right-to-Left

+     */

+    void setLeftToRight(boolean ltr);

+    

+    /**

+     * Should Icon + Value be displayed, or only the Icon?

+     */

+    boolean isIconOnly();

+    /**

+     * Control if only the Icon is shown, or Icon + Value

+     */

+    void setIconOnly(boolean only);

+    

+    /**

+     * How much of the cell width, in %, should be given to

+     *  the min value?

+     */

+    int getWidthMin();

+    void setWidthMin(int width);

+    

+    /**

+     * How much of the cell width, in %, should be given to

+     *  the max value?

+     */

+    int getWidthMax();

+    void setWidthMax(int width);

+    

+    Color getColor();

+    void setColor(Color color);

+    

+    /**

+     * The threshold that defines "everything from here down is minimum"

+     */

+    ConditionalFormattingThreshold getMinThreshold();

+    /**

+     * The threshold that defines "everything from here up is maximum"

+     */

+    ConditionalFormattingThreshold getMaxThreshold();

+}

diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java
index 28dbfbe..766ded1 100644
--- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java
+++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java
@@ -20,6 +20,7 @@
 ==================================================================== */
 package org.apache.poi.ss.usermodel;
 
+import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.DateFormatSymbols;
 import java.text.DecimalFormat;
@@ -38,6 +39,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.poi.ss.util.NumberToTextConverter;
+
 
 /**
  * DataFormatter contains methods for formatting the value stored in an
@@ -731,7 +734,7 @@
      * @see #formatCellValue(Cell)
      */
     public String formatRawCellContents(double value, int formatIndex, String formatString) {
-       return formatRawCellContents(value, formatIndex, formatString, false);
+        return formatRawCellContents(value, formatIndex, formatString, false);
     }
     /**
      * Formats the given raw cell value, based on the supplied
@@ -744,28 +747,42 @@
             if(DateUtil.isValidExcelDate(value)) {
                 Format dateFormat = getFormat(value, formatIndex, formatString);
                 if(dateFormat instanceof ExcelStyleDateFormatter) {
-                   // Hint about the raw excel value
-                   ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(value);
+                    // Hint about the raw excel value
+                    ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(value);
                 }
                 Date d = DateUtil.getJavaDate(value, use1904Windowing);
                 return performDateFormatting(d, dateFormat);
             }
-             // RK: Invalid dates are 255 #s.
-             if (emulateCsv) {
-                 return invalidDateTimeString;
-             }
+            // RK: Invalid dates are 255 #s.
+            if (emulateCsv) {
+                return invalidDateTimeString;
+            }
         }
+        
         // else Number
-            Format numberFormat = getFormat(value, formatIndex, formatString);
-            if (numberFormat == null) {
-                return String.valueOf(value);
-            }
-            // RK: This hack handles scientific notation by adding the missing + back.
-            String result = numberFormat.format(new Double(value));
-            if (result.contains("E") && !result.contains("E-")) {
-                result = result.replaceFirst("E", "E+");
-            }
-            return result;
+        Format numberFormat = getFormat(value, formatIndex, formatString);
+        if (numberFormat == null) {
+            return String.valueOf(value);
+        }
+        
+        // When formatting 'value', double to text to BigDecimal produces more
+        // accurate results than double to Double in JDK8 (as compared to
+        // previous versions). However, if the value contains E notation, this
+        // would expand the values, which we do not want, so revert to
+        // original method.
+        String result;
+        final String textValue = NumberToTextConverter.toText(value);
+        if (textValue.indexOf('E') > -1) {
+            result = numberFormat.format(new Double(value));
+        }
+        else {
+            result = numberFormat.format(new BigDecimal(textValue));
+        }
+        // Complete scientific notation by adding the missing +.
+        if (result.indexOf('E') > -1 && !result.contains("E-")) {
+            result = result.replaceFirst("E", "E+");
+        }
+        return result;
     }
 
     /**
diff --git a/src/java/org/apache/poi/ss/usermodel/DateUtil.java b/src/java/org/apache/poi/ss/usermodel/DateUtil.java
index 79512ef..ca1d7d4 100644
--- a/src/java/org/apache/poi/ss/usermodel/DateUtil.java
+++ b/src/java/org/apache/poi/ss/usermodel/DateUtil.java
@@ -146,7 +146,7 @@
      *  @return Java representation of the date, or null if date is not a valid Excel date
      */
     public static Date getJavaDate(double date, TimeZone tz) {
-       return getJavaDate(date, false, tz);
+       return getJavaDate(date, false, tz, false);
     }
     /**
      *  Given an Excel date with using 1900 date windowing, and
@@ -166,9 +166,9 @@
      *  @see java.util.TimeZone
      */
     public static Date getJavaDate(double date) {
-        return getJavaDate(date, (TimeZone)null);
+        return getJavaDate(date, false, null, false);
     }
-    
+
     /**
      *  Given an Excel date with either 1900 or 1904 date windowing,
      *  converts it to a java.util.Date.
@@ -185,7 +185,7 @@
      *  @return Java representation of the date, or null if date is not a valid Excel date
      */
     public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz) {
-        return getJavaCalendar(date, use1904windowing, tz, false).getTime();
+        return getJavaDate(date, use1904windowing, tz, false);
     }
     
     /**
@@ -205,7 +205,8 @@
      *  @return Java representation of the date, or null if date is not a valid Excel date
      */
     public static Date getJavaDate(double date, boolean use1904windowing, TimeZone tz, boolean roundSeconds) {
-        return getJavaCalendar(date, use1904windowing, tz, roundSeconds).getTime();
+        Calendar calendar = getJavaCalendar(date, use1904windowing, tz, roundSeconds);
+        return calendar == null ? null : calendar.getTime();
     }
     
     /**
@@ -228,10 +229,9 @@
      *  @see java.util.TimeZone
      */
     public static Date getJavaDate(double date, boolean use1904windowing) {
-        return getJavaCalendar(date, use1904windowing, null, false).getTime();
+        return getJavaDate(date, use1904windowing, null, false);
     }
 
-
     public static void setCalendar(Calendar calendar, int wholeDays,
             int millisecondsInDay, boolean use1904windowing, boolean roundSeconds) {
         int startYear = 1900;
@@ -567,7 +567,7 @@
 
     private static int daysInPriorYears(int yr, boolean use1904windowing)
     {
-        if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1900)) {
+        if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1904)) {
             throw new IllegalArgumentException("'year' must be 1900 or greater");
         }
 
diff --git a/src/java/org/apache/poi/ss/usermodel/FontFormatting.java b/src/java/org/apache/poi/ss/usermodel/FontFormatting.java
index 2298d79..a6f21bd 100644
--- a/src/java/org/apache/poi/ss/usermodel/FontFormatting.java
+++ b/src/java/org/apache/poi/ss/usermodel/FontFormatting.java
@@ -22,9 +22,6 @@
 /**

  * High level representation for Font Formatting component

  * of Conditional Formatting settings

- *

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

  */

 public interface FontFormatting {

     /** Escapement type - None */

@@ -66,15 +63,26 @@
     void setEscapementType(short escapementType);

 

     /**

-     * @return font color index

+     * @return font colour index, or 0 if not indexed (XSSF only)

      */

     short getFontColorIndex();

 

-

     /**

-     * @param color font color index

+     * Sets the indexed colour to use

+     * @param color font colour index

      */

     void setFontColorIndex(short color);

+    

+    /**

+     * @return The colour of the font, or null if no colour applied

+     */

+    Color getFontColor();

+    

+    /**

+     * Sets the colour to use

+     * @param color font colour to use

+     */

+    void setFontColor(Color color);

 

     /**

      * gets the height of the font in 1/20th point units

diff --git a/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java b/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java
new file mode 100644
index 0000000..d5212e5
--- /dev/null
+++ b/src/java/org/apache/poi/ss/usermodel/IconMultiStateFormatting.java
@@ -0,0 +1,127 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.ss.usermodel;

+

+/**

+ * High level representation for the Icon / Multi-State Formatting 

+ *  component of Conditional Formatting settings

+ */

+public interface IconMultiStateFormatting {

+    public enum IconSet {

+        /** Green Up / Yellow Side / Red Down arrows */

+        GYR_3_ARROW(0, 3, "3Arrows"),

+        /** Grey Up / Side / Down arrows */

+        GREY_3_ARROWS(1, 3, "3ArrowsGray"),

+        /** Green / Yellow / Red flags */

+        GYR_3_FLAGS(2, 3, "3Flags"),

+        /** Green / Yellow / Red traffic lights (no background). Default */

+        GYR_3_TRAFFIC_LIGHTS(3, 3, "3TrafficLights1"),

+        /** Green / Yellow / Red traffic lights on a black square background. 

+         * Note, MS-XLS docs v20141018 say this is id=5 but seems to be id=4 */

+        GYR_3_TRAFFIC_LIGHTS_BOX(4, 3, "3TrafficLights2"),

+        /** Green Circle / Yellow Triangle / Red Diamond.

+         * Note, MS-XLS docs v20141018 say this is id=4 but seems to be id=5 */ 

+        GYR_3_SHAPES(5, 3, "3Signs"),

+        /** Green Tick / Yellow ! / Red Cross on a circle background */

+        GYR_3_SYMBOLS_CIRCLE(6, 3, "3Symbols"),

+        /** Green Tick / Yellow ! / Red Cross (no background) */

+        GYR_3_SYMBOLS(7, 3, "3Symbols2"),

+        /** Green Up / Yellow NE / Yellow SE / Red Down arrows */

+        GYR_4_ARROWS(8, 4, "4Arrows"),

+        /** Grey Up / NE / SE / Down arrows */

+        GREY_4_ARROWS(9, 4, "4ArrowsGray"),

+        /** Red / Light Red / Grey / Black traffic lights */

+        RB_4_TRAFFIC_LIGHTS(0xA, 4, "4RedToBlack"),

+        RATINGS_4(0xB, 4, "4Rating"),

+        /** Green / Yellow / Red / Black traffic lights */

+        GYRB_4_TRAFFIC_LIGHTS(0xC, 4, "4TrafficLights"),

+        GYYYR_5_ARROWS(0xD, 5, "5Arrows"),

+        GREY_5_ARROWS(0xE, 5, "5ArrowsGray"),

+        RATINGS_5(0xF, 5, "5Rating"),

+        QUARTERS_5(0x10, 5, "5Quarters");

+        

+        protected static final IconSet DEFAULT_ICONSET = IconSet.GYR_3_TRAFFIC_LIGHTS;

+        

+        /** Numeric ID of the icon set */

+        public int id;

+        /** How many icons in the set */

+        public final int num;

+        /** Name (system) of the set */

+        public final String name;

+        

+        public String toString() {

+            return id + " - " + name;

+        }

+        

+        public static IconSet byId(int id) {

+            return values()[id];

+        }

+        public static IconSet byName(String name) {

+            for (IconSet set : values()) {

+                if (set.name.equals(name)) return set;

+            }

+            return null;

+        }

+        

+        private IconSet(int id, int num, String name) {

+            this.id = id; this.num = num; this.name = name;

+        }

+    }

+    

+    /**

+     * Get the Icon Set used

+     */

+    IconSet getIconSet();

+    

+    /**

+     * Changes the Icon Set used

+     * 

+     * <p>If the new Icon Set has a different number of

+     *  icons to the old one, you <em>must</em> update the

+     *  thresholds before saving!</p>

+     */

+    void setIconSet(IconSet set);

+    

+    /**

+     * Should Icon + Value be displayed, or only the Icon?

+     */

+    boolean isIconOnly();

+    /**

+     * Control if only the Icon is shown, or Icon + Value

+     */

+    void setIconOnly(boolean only);

+    

+    boolean isReversed();

+    void setReversed(boolean reversed);

+    

+    /**

+     * Gets the list of thresholds

+     */

+    ConditionalFormattingThreshold[] getThresholds();

+    /**

+     * Sets the of thresholds. The number must match

+     *  {@link IconSet#num} for the current {@link #getIconSet()}

+     */

+    void setThresholds(ConditionalFormattingThreshold[] thresholds);

+    /**

+     * Creates a new, empty Threshold

+     */

+    ConditionalFormattingThreshold createThreshold();

+}

diff --git a/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java b/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java
index 2739c96..0311ffb 100644
--- a/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java
+++ b/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java
@@ -63,14 +63,16 @@
     public final static short     LEAST_DOTS          = 18 ;

 

     short getFillBackgroundColor();

-

     short getFillForegroundColor();

+    Color getFillBackgroundColorColor();

+    Color getFillForegroundColorColor();

 

     short getFillPattern();

 

     void setFillBackgroundColor(short bg);

-

     void setFillForegroundColor(short fg);

+    void setFillBackgroundColor(Color bg);

+    void setFillForegroundColor(Color fg);

 

     void setFillPattern(short fp);

 }

diff --git a/src/java/org/apache/poi/ss/usermodel/Sheet.java b/src/java/org/apache/poi/ss/usermodel/Sheet.java
index 987a35e..f099051 100644
--- a/src/java/org/apache/poi/ss/usermodel/Sheet.java
+++ b/src/java/org/apache/poi/ss/usermodel/Sheet.java
@@ -321,6 +321,13 @@
     public CellRangeAddress getMergedRegion(int index);
 
     /**
+     * Returns the list of merged regions.
+     *
+     * @return the list of merged regions
+     */
+    public List<CellRangeAddress> getMergedRegions();
+
+    /**
      *  Returns an iterator of the physical rows
      *
      * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
diff --git a/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java b/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java
index e20a8f7..a28c342 100644
--- a/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java
+++ b/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java
@@ -19,17 +19,15 @@
 

 package org.apache.poi.ss.usermodel;

 

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;

 import org.apache.poi.ss.util.CellRangeAddress;

 

 /**

  * The 'Conditional Formatting' facet of <tt>Sheet</tt>

  *

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

  * @since 3.8

  */

 public interface SheetConditionalFormatting {

-

     /**

      * Add a new Conditional Formatting to the sheet.

      *

@@ -58,7 +56,7 @@
      * Add a new Conditional Formatting set to the sheet.

      *

      * @param regions - list of rectangular regions to apply conditional formatting rules

-     * @param cfRules - set of up to three conditional formatting rules

+     * @param cfRules - set of up to conditional formatting rules (max 3 for Excel pre-2007)

      *

      * @return index of the newly created Conditional Formatting object

      */

@@ -86,7 +84,7 @@
      * <p>

      * The created conditional formatting rule compares a cell value

      * to a formula calculated result, using the specified operator.

-     * The type  of the created condition is {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}

+     * The type  of the created condition is {@link ConditionType#CELL_VALUE_IS}

      * </p>

      *

      * @param comparisonOperation - MUST be a constant value from

@@ -115,7 +113,7 @@
      * Create a conditional formatting rule that compares a cell value

      * to a formula calculated result, using an operator     *

      * <p>

-      * The type  of the created condition is {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}

+      * The type  of the created condition is {@link ConditionType#CELL_VALUE_IS}

      * </p>

      *

      * @param comparisonOperation  MUST be a constant value from

@@ -132,13 +130,25 @@
      *  When the formula result is true, the cell is highlighted.

      *

      * <p>

-     *  The type of the created format condition is  {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA}

+     *  The type of the created format condition is  {@link ConditionType#FORMULA}

      * </p>

      * @param formula   the formula to evaluate. MUST be a Boolean function.

      */

     ConditionalFormattingRule createConditionalFormattingRule(String formula);

 

     /**

+     * Create an Icon Set / Multi-State conditional formatting rule.

+     * <p>The thresholds for it will be created, but will be empty

+     *  and require configuring with 

+     *  {@link ConditionalFormattingRule#getMultiStateFormatting()}

+     *  then

+     *  {@link IconMultiStateFormatting#getThresholds()}

+     */

+    ConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet);

+

+    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs

+    

+    /**

     * Gets Conditional Formatting object at a particular index

     *

     * @param index  0-based index of the Conditional Formatting object to fetch

diff --git a/src/java/org/apache/poi/ss/util/AreaReference.java b/src/java/org/apache/poi/ss/util/AreaReference.java
index d593888..b0a6913 100644
--- a/src/java/org/apache/poi/ss/util/AreaReference.java
+++ b/src/java/org/apache/poi/ss/util/AreaReference.java
@@ -35,13 +35,23 @@
     private final CellReference _firstCell;
     private final CellReference _lastCell;
     private final boolean _isSingleCell;
+    private SpreadsheetVersion _version;
 
     /**
+     * @deprecated Prefer supplying a version.
+     */
+    @Deprecated
+    public AreaReference(String reference) {
+        this(reference, SpreadsheetVersion.EXCEL97);
+    }
+    
+    /**
      * Create an area ref from a string representation.  Sheet names containing special characters should be
      * delimited and escaped as per normal syntax rules for formulas.<br/> 
      * The area reference must be contiguous (i.e. represent a single rectangle, not a union of rectangles)
      */
-    public AreaReference(String reference) {
+    public AreaReference(String reference, SpreadsheetVersion version) {
+        _version = version;
         if(! isContiguous(reference)) {
             throw new IllegalArgumentException(
                     "References passed to the AreaReference must be contiguous, " +
@@ -169,30 +179,34 @@
        return false;
     }
 
-    public static AreaReference getWholeRow(String start, String end) {
-        return new AreaReference("$A" + start + ":$IV" + end);
+    public static AreaReference getWholeRow(SpreadsheetVersion version, String start, String end) {
+        return new AreaReference("$A" + start + ":$" + version.getLastColumnName() + end, version);
     }
 
-    public static AreaReference getWholeColumn(String start, String end) {
-        return new AreaReference(start + "$1:" + end + "$65536");
+    public static AreaReference getWholeColumn(SpreadsheetVersion version, String start, String end) {
+        return new AreaReference(start + "$1:" + end + "$" + version.getMaxRows(), version);
     }
 
     /**
      * Is the reference for a whole-column reference,
      *  such as C:C or D:G ?
      */
-    public static boolean isWholeColumnReference(CellReference topLeft, CellReference botRight) {
+    public static boolean isWholeColumnReference(SpreadsheetVersion version, CellReference topLeft, CellReference botRight) {
+        if (null == version) {
+            version = SpreadsheetVersion.EXCEL97; // how the code used to behave.
+        }
+        
         // These are represented as something like
         //   C$1:C$65535 or D$1:F$0
         // i.e. absolute from 1st row to 0th one
         if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
-            botRight.getRow() == SpreadsheetVersion.EXCEL97.getLastRowIndex() && botRight.isRowAbsolute()) {
+            botRight.getRow() == version.getLastRowIndex() && botRight.isRowAbsolute()) {
             return true;
         }
         return false;
     }
     public boolean isWholeColumnReference() {
-        return isWholeColumnReference(_firstCell, _lastCell);
+        return isWholeColumnReference(_version, _firstCell, _lastCell);
     }
 
     /**
diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java b/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java
index 2343226..4b5b104 100644
--- a/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java
+++ b/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java
@@ -24,8 +24,6 @@
  * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
  *
  * Common subclass of 8-bit and 16-bit versions
- *
- * @author Josh Micich
  */
 public abstract class CellRangeAddressBase {
 
diff --git a/src/java/org/apache/poi/ss/util/SheetUtil.java b/src/java/org/apache/poi/ss/util/SheetUtil.java
index 6b55e22..cc32229 100644
--- a/src/java/org/apache/poi/ss/util/SheetUtil.java
+++ b/src/java/org/apache/poi/ss/util/SheetUtil.java
@@ -93,10 +93,9 @@
      * @param defaultCharWidth the width of a single character
      * @param formatter formatter used to prepare the text to be measured
      * @param useMergedCells    whether to use merged cells
-     * @return  the width in pixels
+     * @return  the width in pixels or -1 if cell is empty
      */
     public static double getCellWidth(Cell cell, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) {
-
         Sheet sheet = cell.getSheet();
         Workbook wb = sheet.getWorkbook();
         Row row = cell.getRow();
@@ -123,9 +122,6 @@
 
         Font font = wb.getFontAt(style.getFontIndex());
 
-        AttributedString str;
-        TextLayout layout;
-
         double width = -1;
         if (cellType == Cell.CELL_TYPE_STRING) {
             RichTextString rt = cell.getRichStringCellValue();
@@ -133,30 +129,14 @@
             for (int i = 0; i < lines.length; i++) {
                 String txt = lines[i] + defaultChar;
 
-                str = new AttributedString(txt);
+                AttributedString str = new AttributedString(txt);
                 copyAttributes(font, str, 0, txt.length());
 
                 if (rt.numFormattingRuns() > 0) {
                     // TODO: support rich text fragments
                 }
 
-                layout = new TextLayout(str.getIterator(), fontRenderContext);
-                if(style.getRotation() != 0){
-                    /*
-                     * Transform the text using a scale so that it's height is increased by a multiple of the leading,
-                     * and then rotate the text before computing the bounds. The scale results in some whitespace around
-                     * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
-                     * is added by the standard Excel autosize.
-                     */
-                    AffineTransform trans = new AffineTransform();
-                    trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
-                    trans.concatenate(
-                    AffineTransform.getScaleInstance(1, fontHeightMultiple)
-                    );
-                    width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
-                } else {
-                    width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
-                }
+                width = getCellWidth(defaultCharWidth, colspan, style, width, str);
             }
         } else {
             String sval = null;
@@ -172,66 +152,49 @@
             }
             if(sval != null) {
                 String txt = sval + defaultChar;
-                str = new AttributedString(txt);
+                AttributedString str = new AttributedString(txt);
                 copyAttributes(font, str, 0, txt.length());
 
-                layout = new TextLayout(str.getIterator(), fontRenderContext);
-                if(style.getRotation() != 0){
-                    /*
-                     * Transform the text using a scale so that it's height is increased by a multiple of the leading,
-                     * and then rotate the text before computing the bounds. The scale results in some whitespace around
-                     * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
-                     * is added by the standard Excel autosize.
-                     */
-                    AffineTransform trans = new AffineTransform();
-                    trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
-                    trans.concatenate(
-                    AffineTransform.getScaleInstance(1, fontHeightMultiple)
-                    );
-                    width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
-                } else {
-                    width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention());
-                }
+                width = getCellWidth(defaultCharWidth, colspan, style, width, str);
             }
         }
         return width;
     }
 
+    private static double getCellWidth(int defaultCharWidth, int colspan,
+            CellStyle style, double width, AttributedString str) {
+        TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
+        if(style.getRotation() != 0){
+            /*
+             * Transform the text using a scale so that it's height is increased by a multiple of the leading,
+             * and then rotate the text before computing the bounds. The scale results in some whitespace around
+             * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
+             * is added by the standard Excel autosize.
+             */
+            AffineTransform trans = new AffineTransform();
+            trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
+            trans.concatenate(
+            AffineTransform.getScaleInstance(1, fontHeightMultiple)
+            );
+            width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + style.getIndention());
+        } else {
+            width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + style.getIndention());
+        }
+        return width;
+    }
+
     /**
      * Compute width of a column and return the result
      *
      * @param sheet the sheet to calculate
      * @param column    0-based index of the column
      * @param useMergedCells    whether to use merged cells
-     * @return  the width in pixels
+     * @return  the width in pixels or -1 if all cells are empty
      */
-    public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells){
-        AttributedString str;
-        TextLayout layout;
-
-        Workbook wb = sheet.getWorkbook();
-        DataFormatter formatter = new DataFormatter();
-        Font defaultFont = wb.getFontAt((short) 0);
-
-        str = new AttributedString(String.valueOf(defaultChar));
-        copyAttributes(defaultFont, str, 0, 1);
-        layout = new TextLayout(str.getIterator(), fontRenderContext);
-        int defaultCharWidth = (int)layout.getAdvance();
-
-        double width = -1;
-        for (Row row : sheet) {
-            Cell cell = row.getCell(column);
-
-            if (cell == null) {
-                continue;
-            }
-
-            double cellWidth = getCellWidth(cell, defaultCharWidth, formatter, useMergedCells);
-            width = Math.max(width, cellWidth);
-        }
-        return width;
+    public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells) {
+        return getColumnWidth(sheet, column, useMergedCells, sheet.getFirstRowNum(), sheet.getLastRowNum());
     }
-
+    
     /**
      * Compute width of a column based on a subset of the rows and return the result
      *
@@ -240,19 +203,16 @@
      * @param useMergedCells    whether to use merged cells
      * @param firstRow  0-based index of the first row to consider (inclusive)
      * @param lastRow   0-based index of the last row to consider (inclusive)
-     * @return  the width in pixels
+     * @return  the width in pixels or -1 if cell is empty
      */
     public static double getColumnWidth(Sheet sheet, int column, boolean useMergedCells, int firstRow, int lastRow){
-        AttributedString str;
-        TextLayout layout;
-
         Workbook wb = sheet.getWorkbook();
         DataFormatter formatter = new DataFormatter();
         Font defaultFont = wb.getFontAt((short) 0);
 
-        str = new AttributedString(String.valueOf(defaultChar));
+        AttributedString str = new AttributedString(String.valueOf(defaultChar));
         copyAttributes(defaultFont, str, 0, 1);
-        layout = new TextLayout(str.getIterator(), fontRenderContext);
+        TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
         int defaultCharWidth = (int)layout.getAdvance();
 
         double width = -1;
@@ -274,6 +234,30 @@
     }
 
     /**
+     * Check if the Fonts are installed correctly so that Java can compute the size of
+     * columns. 
+     * 
+     * If a Cell uses a Font which is not available on the operating system then Java may 
+     * fail to return useful Font metrics and thus lead to an auto-computed size of 0.
+     * 
+     *  This method allows to check if computing the sizes for a given Font will succeed or not.
+     *
+     * @param font The Font that is used in the Cell
+     * @return true if computing the size for this Font will succeed, false otherwise
+     */
+    public static boolean canComputeColumnWidht(Font font) {
+        AttributedString str = new AttributedString("1");
+        copyAttributes(font, str, 0, "1".length());
+
+        TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
+        if(layout.getBounds().getWidth() > 0) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Copy text attributes from the supplied Font to Java2D AttributedString
      */
     private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) {
diff --git a/src/java/org/apache/poi/util/BitFieldFactory.java b/src/java/org/apache/poi/util/BitFieldFactory.java
index 4159074..047d5cb 100644
--- a/src/java/org/apache/poi/util/BitFieldFactory.java
+++ b/src/java/org/apache/poi/util/BitFieldFactory.java
@@ -21,11 +21,8 @@
 import java.util.*;
 
 /**
- * Returns immutable Btfield instances.
- *
- * @author Jason Height (jheight at apache dot org)
+ * Returns immutable Bitfield instances.
  */
-
 public class BitFieldFactory {
     private static Map<Integer, BitField> instances = new HashMap<Integer, BitField>();
 
diff --git a/src/java/org/apache/poi/util/CloseIgnoringInputStream.java b/src/java/org/apache/poi/util/CloseIgnoringInputStream.java
index f4896a8..66e42c2 100644
--- a/src/java/org/apache/poi/util/CloseIgnoringInputStream.java
+++ b/src/java/org/apache/poi/util/CloseIgnoringInputStream.java
@@ -20,13 +20,11 @@
 import java.io.FilterInputStream;
 import java.io.InputStream;
 
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-
 /**
  * A wrapper around an {@link InputStream}, which 
  *  ignores close requests made to it.
  *
- * Useful with {@link POIFSFileSystem}, where you want
+ * Useful with {@link org.apache.poi.poifs.filesystem.POIFSFileSystem}, where you want
  *  to control the close yourself.
  */
 public class CloseIgnoringInputStream extends FilterInputStream {
diff --git a/src/java/org/apache/poi/util/DrawingDump.java b/src/java/org/apache/poi/util/DrawingDump.java
index 1055ab2..4eb6a2a 100644
--- a/src/java/org/apache/poi/util/DrawingDump.java
+++ b/src/java/org/apache/poi/util/DrawingDump.java
@@ -18,12 +18,12 @@
         
 package org.apache.poi.util;
 
+import java.io.File;
+import java.io.IOException;
+
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-
-import java.io.FileInputStream;
-import java.io.IOException;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 
 /**
  * Dump out the aggregated escher records
@@ -32,8 +32,8 @@
 {
     public static void main( String[] args ) throws IOException
     {
-        POIFSFileSystem fs      =
-                new POIFSFileSystem(new FileInputStream(args[0]));
+        NPOIFSFileSystem fs      =
+                new NPOIFSFileSystem(new File(args[0]));
         HSSFWorkbook wb = new HSSFWorkbook(fs);
         try {
             System.out.println( "Drawing group:" );
diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java
index 3c086ba..02d9b6a 100644
--- a/src/java/org/apache/poi/util/HexDump.java
+++ b/src/java/org/apache/poi/util/HexDump.java
@@ -245,12 +245,15 @@
     {
         StringBuffer retVal = new StringBuffer();
         retVal.append('[');
-        for(int x = 0; x < value.length; x++)
+        if (value != null && value.length > 0)
         {
-            if (x>0) {
-                retVal.append(", ");
+            for(int x = 0; x < value.length; x++)
+            {
+                if (x>0) {
+                    retVal.append(", ");
+                }
+                retVal.append(toHex(value[x]));
             }
-            retVal.append(toHex(value[x]));
         }
         retVal.append(']');
         return retVal.toString();
diff --git a/src/java/org/apache/poi/util/IOUtils.java b/src/java/org/apache/poi/util/IOUtils.java
index 4f18214..f1d5a23 100644
--- a/src/java/org/apache/poi/util/IOUtils.java
+++ b/src/java/org/apache/poi/util/IOUtils.java
@@ -22,120 +22,149 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PushbackInputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.ReadableByteChannel;
 import java.util.zip.CRC32;
 import java.util.zip.Checksum;
 
+import org.apache.poi.EmptyFileException;
+
 public final class IOUtils {
+    private static final POILogger logger = POILogFactory.getLogger( IOUtils.class );
 
-    private static final POILogger logger = POILogFactory
-            .getLogger( IOUtils.class );
+    private IOUtils() {
+        // no instances of this class
+    }
 
-	private IOUtils() {
-		// no instances of this class
-	}
+    /**
+     * Peeks at the first 8 bytes of the stream. Returns those bytes, but
+     *  with the stream unaffected. Requires a stream that supports mark/reset,
+     *  or a PushbackInputStream. If the stream has &gt;0 but &lt;8 bytes, 
+     *  remaining bytes will be zero.
+     * @throws EmptyFileException if the stream is empty
+     */
+    public static byte[] peekFirst8Bytes(InputStream stream) throws IOException, EmptyFileException {
+        // We want to peek at the first 8 bytes
+        stream.mark(8);
 
-	/**
-	 * Reads all the data from the input stream, and returns the bytes read.
-	 */
-	public static byte[] toByteArray(InputStream stream) throws IOException {
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] header = new byte[8];
+        int read = IOUtils.readFully(stream, header);
 
-		byte[] buffer = new byte[4096];
-		int read = 0;
-		while (read != -1) {
-			read = stream.read(buffer);
-			if (read > 0) {
-				baos.write(buffer, 0, read);
-			}
-		}
+        if (read < 1)
+            throw new EmptyFileException();
 
-		return baos.toByteArray();
-	}
+        // Wind back those 8 bytes
+        if(stream instanceof PushbackInputStream) {
+            PushbackInputStream pin = (PushbackInputStream)stream;
+            pin.unread(header);
+        } else {
+            stream.reset();
+        }
 
-   /**
-    * Returns an array (that shouldn't be written to!) of the
-    *  ByteBuffer. Will be of the requested length, or possibly
-    *  longer if that's easier.
-    */
-   public static byte[] toByteArray(ByteBuffer buffer, int length) {
-      if(buffer.hasArray() && buffer.arrayOffset() == 0) {
-         // The backing array should work out fine for us
-         return buffer.array();
-      }
-      
-      byte[] data = new byte[length];
-      buffer.get(data);
-      return data;
-   }
+        return header;
+    }
 
-	/**
-	 * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt>
-	 */
-	public static int readFully(InputStream in, byte[] b) throws IOException {
-		return readFully(in, b, 0, b.length);
-	}
+    /**
+     * Reads all the data from the input stream, and returns the bytes read.
+     */
+    public static byte[] toByteArray(InputStream stream) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
-	/**
-	 * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure
-	 * that the entire len number of bytes is read.
-	 * <p>
-	 * If the end of file is reached before any bytes are read, returns -1. If
-	 * the end of the file is reached after some bytes are read, returns the
-	 * number of bytes read. If the end of the file isn't reached before len
-	 * bytes have been read, will return len bytes.
-	 */
-	public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException {
-		int total = 0;
-		while (true) {
-			int got = in.read(b, off + total, len - total);
-			if (got < 0) {
-				return (total == 0) ? -1 : total;
-			}
-			total += got;
-			if (total == len) {
-				return total;
-			}
-		}
-	}
-	
-   /**
-    * Same as the normal <tt>channel.read(b)</tt>, but tries to ensure
-    * that the entire len number of bytes is read.
-    * <p>
-    * If the end of file is reached before any bytes are read, returns -1. If
-    * the end of the file is reached after some bytes are read, returns the
-    * number of bytes read. If the end of the file isn't reached before len
-    * bytes have been read, will return len bytes.
-    */
-	public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException {
-      int total = 0;
-      while (true) {
-         int got = channel.read(b);
-         if (got < 0) {
-            return (total == 0) ? -1 : total;
-         }
-         total += got;
-         if (total == b.capacity() || b.position() == b.capacity()) {
-            return total;
-         }
-      }
-	}
-	
-	/**
-	 * Copies all the data from the given InputStream to the OutputStream. It
-	 * leaves both streams open, so you will still need to close them once done.
-	 */
-	public static void copy(InputStream inp, OutputStream out) throws IOException {
-		byte[] buff = new byte[4096];
-		int count;
-		while ((count = inp.read(buff)) != -1) {
-			if (count > 0) {
-				out.write(buff, 0, count);
-			}
-		}
-	}
+        byte[] buffer = new byte[4096];
+        int read = 0;
+        while (read != -1) {
+            read = stream.read(buffer);
+            if (read > 0) {
+                baos.write(buffer, 0, read);
+            }
+        }
+
+        return baos.toByteArray();
+    }
+
+    /**
+     * Returns an array (that shouldn't be written to!) of the
+     *  ByteBuffer. Will be of the requested length, or possibly
+     *  longer if that's easier.
+     */
+    public static byte[] toByteArray(ByteBuffer buffer, int length) {
+        if(buffer.hasArray() && buffer.arrayOffset() == 0) {
+            // The backing array should work out fine for us
+            return buffer.array();
+        }
+
+        byte[] data = new byte[length];
+        buffer.get(data);
+        return data;
+    }
+
+    /**
+     * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt>
+     */
+    public static int readFully(InputStream in, byte[] b) throws IOException {
+        return readFully(in, b, 0, b.length);
+    }
+
+    /**
+     * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure
+     * that the entire len number of bytes is read.
+     * <p>
+     * If the end of file is reached before any bytes are read, returns -1. If
+     * the end of the file is reached after some bytes are read, returns the
+     * number of bytes read. If the end of the file isn't reached before len
+     * bytes have been read, will return len bytes.
+     */
+    public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException {
+        int total = 0;
+        while (true) {
+            int got = in.read(b, off + total, len - total);
+            if (got < 0) {
+                return (total == 0) ? -1 : total;
+            }
+            total += got;
+            if (total == len) {
+                return total;
+            }
+        }
+    }
+
+    /**
+     * Same as the normal <tt>channel.read(b)</tt>, but tries to ensure
+     * that the entire len number of bytes is read.
+     * <p>
+     * If the end of file is reached before any bytes are read, returns -1. If
+     * the end of the file is reached after some bytes are read, returns the
+     * number of bytes read. If the end of the file isn't reached before len
+     * bytes have been read, will return len bytes.
+     */
+    public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException {
+        int total = 0;
+        while (true) {
+            int got = channel.read(b);
+            if (got < 0) {
+                return (total == 0) ? -1 : total;
+            }
+            total += got;
+            if (total == b.capacity() || b.position() == b.capacity()) {
+                return total;
+            }
+        }
+    }
+
+    /**
+     * Copies all the data from the given InputStream to the OutputStream. It
+     * leaves both streams open, so you will still need to close them once done.
+     */
+    public static void copy(InputStream inp, OutputStream out) throws IOException {
+        byte[] buff = new byte[4096];
+        int count;
+        while ((count = inp.read(buff)) != -1) {
+            if (count > 0) {
+                out.write(buff, 0, count);
+            }
+        }
+    }
 
     public static long calculateChecksum(byte[] data) {
         Checksum sum = new CRC32();
@@ -150,14 +179,10 @@
      * @param closeable
      *            resource to close
      */
-    public static void closeQuietly( final Closeable closeable )
-    {
-        try
-        {
+    public static void closeQuietly( final Closeable closeable ) {
+        try {
             closeable.close();
-        }
-        catch ( Exception exc )
-        {
+        } catch ( Exception exc ) {
             logger.log( POILogger.ERROR, "Unable to close resource: " + exc,
                     exc );
         }
diff --git a/src/java/org/apache/poi/util/NullLogger.java b/src/java/org/apache/poi/util/NullLogger.java
index 95c8c5d..24643c8 100644
--- a/src/java/org/apache/poi/util/NullLogger.java
+++ b/src/java/org/apache/poi/util/NullLogger.java
@@ -27,12 +27,10 @@
  * @author Glen Stampoultzis (glens at apache.org)
  * @author Nicola Ken Barozzi (nicolaken at apache.org)
  */
-public class NullLogger extends POILogger
-{
+public class NullLogger extends POILogger {
     @Override
-    public void initialize(final String cat)
-    {
-       //do nothing
+    public void initialize(final String cat){
+       // do nothing
     }
 
     /**
@@ -45,147 +43,7 @@
     @Override
     public void log(final int level, final Object obj1)
     {
-        //do nothing
-    }
-
-    /**
-     * Check if a logger is enabled to log at the specified level
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     */
-
-    @Override
-    public boolean check(final int level)
-    {
-       return false;
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first object to place in the message
-     * @param obj2 second object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     * @param obj7 seventh Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6, final Object obj7)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     * @param obj7 seventh Object to place in the message
-     * @param obj8 eighth Object to place in the message
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6, final Object obj7, final Object obj8)
-    {
-       //do nothing
+        // do nothing
     }
 
     /**
@@ -195,289 +53,19 @@
      * @param obj1 The object to log.  This is converted to a string.
      * @param exception An exception to be logged
      */
-
-    @Override
-    public void log(final int level, final Object obj1,
-                    final Throwable exception)
-    {
-       //do nothing
+    public void log(int level, Object obj1, final Throwable exception) {
+        // do nothing
     }
 
+    
     /**
-     * Log a message. Lazily appends Object parameters together.
+     * Check if a logger is enabled to log at the specified level
      *
      * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param exception An exception to be logged
      */
-
     @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Throwable exception)
-    {
-       //do nothing
+    public boolean check(final int level) {
+       return false;
     }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param exception An error message to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Throwable exception)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param exception An exception to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4,
-                    final Throwable exception)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param exception An exception to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Throwable exception)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param exception An exception to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6, final Throwable exception)
-    {
-       //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param obj7 seventh object to place in the message
-     * @param exception An exception to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6, final Object obj7,
-                    final Throwable exception)
-    {
-      //do nothing
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param obj7 seventh object to place in the message
-     * @param obj8 eighth object to place in the message
-     * @param exception An exception to be logged
-     */
-
-    @Override
-    public void log(final int level, final Object obj1, final Object obj2,
-                    final Object obj3, final Object obj4, final Object obj5,
-                    final Object obj6, final Object obj7, final Object obj8,
-                    final Throwable exception)
-    {
-       //do nothing
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     */
-
-    @Override
-    public void logFormatted(final int level, final String message,
-                             final Object obj1)
-    {
-       //do nothing
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     */
-
-    @Override
-    public void logFormatted(final int level, final String message,
-                             final Object obj1, final Object obj2)
-    {
-       //do nothing
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     * @param obj3 The third object to match against.
-     */
-
-    @Override
-    public void logFormatted(final int level, final String message,
-                             final Object obj1, final Object obj2,
-                             final Object obj3)
-    {
-       //do nothing
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     * @param obj3 The third object to match against.
-     * @param obj4 The forth object to match against.
-     */
-
-    @Override
-    public void logFormatted(final int level, final String message,
-                             final Object obj1, final Object obj2,
-                             final Object obj3, final Object obj4)
-    {
-       //do nothing
-    }
-
 }
 
diff --git a/src/java/org/apache/poi/util/POILogFactory.java b/src/java/org/apache/poi/util/POILogFactory.java
index 641949c..7af73e3 100644
--- a/src/java/org/apache/poi/util/POILogFactory.java
+++ b/src/java/org/apache/poi/util/POILogFactory.java
@@ -15,7 +15,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 
 package org.apache.poi.util;
 
@@ -30,20 +30,18 @@
  * @author Marc Johnson (mjohnson at apache dot org)
  * @author Nicola Ken Barozzi (nicolaken at apache.org)
  */
-
-public class POILogFactory
-{
-
+@Internal
+public final class POILogFactory {
     /**
      * Map of POILogger instances, with classes as keys
      */
-    private static Map<String,POILogger> _loggers = new HashMap<String,POILogger>();;
+    private static Map<String,POILogger> _loggers = new HashMap<String,POILogger>();
 
     /**
      * A common instance of NullLogger, as it does nothing
      *  we only need the one
      */
-    private static POILogger _nullLogger = new NullLogger();
+    private static final POILogger _nullLogger = new NullLogger();
     /**
      * The name of the class to use. Initialised the
      *  first time we need it
@@ -53,9 +51,7 @@
     /**
      * Construct a POILogFactory.
      */
-    private POILogFactory()
-    {
-    }
+    private POILogFactory() {}
 
     /**
      * Get a logger, based on a class name
@@ -64,12 +60,10 @@
      *
      * @return a POILogger for the specified class
      */
-
-    public static POILogger getLogger(final Class<?> theclass)
-    {
+    public static POILogger getLogger(final Class<?> theclass) {
         return getLogger(theclass.getName());
     }
-    
+
     /**
      * Get a logger, based on a String
      *
@@ -77,11 +71,9 @@
      *
      * @return a POILogger for the specified class
      */
-
-    public static POILogger getLogger(final String cat)
-    {
+    public static POILogger getLogger(final String cat) {
         POILogger logger = null;
-        
+
         // If we haven't found out what logger to use yet,
         //  then do so now
         // Don't look it up until we're first asked, so
@@ -91,40 +83,40 @@
         	try {
         		_loggerClassName = System.getProperty("org.apache.poi.util.POILogger");
         	} catch(Exception e) {}
-        	
+
         	// Use the default logger if none specified,
         	//  or none could be fetched
         	if(_loggerClassName == null) {
-        		_loggerClassName = _nullLogger.getClass().getName();
+                _loggerClassName = _nullLogger.getClass().getName();
         	}
         }
-        
+
         // Short circuit for the null logger, which
         //  ignores all categories
         if(_loggerClassName.equals(_nullLogger.getClass().getName())) {
         	return _nullLogger;
         }
 
-        
+
         // Fetch the right logger for them, creating
-        //  it if that's required 
-        if (_loggers.containsKey(cat)) {
-            logger = _loggers.get(cat);
-        } else {
+        //  it if that's required
+        logger = _loggers.get(cat);
+        if (logger == null) {
             try {
-              @SuppressWarnings("unchecked")
-			Class<? extends POILogger> loggerClass = 
-                 (Class<? extends POILogger>)Class.forName(_loggerClassName);
-              logger = loggerClass.newInstance();
-              logger.initialize(cat);
+                @SuppressWarnings("unchecked")
+                Class<? extends POILogger> loggerClass =
+                    (Class<? extends POILogger>) Class.forName(_loggerClassName);
+                logger = loggerClass.newInstance();
+                logger.initialize(cat);
             } catch(Exception e) {
-              // Give up and use the null logger
-              logger = _nullLogger;
+                // Give up and use the null logger
+                logger = _nullLogger;
+                _loggerClassName = _nullLogger.getClass().getName();
             }
-            
+
             // Save for next time
             _loggers.put(cat, logger);
         }
         return logger;
     }
-}   // end public class POILogFactory
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/util/POILogger.java b/src/java/org/apache/poi/util/POILogger.java
index 4088ec2..d892366 100644
--- a/src/java/org/apache/poi/util/POILogger.java
+++ b/src/java/org/apache/poi/util/POILogger.java
@@ -30,6 +30,7 @@
  * @author Glen Stampoultzis (glens at apache.org)
  * @author Nicola Ken Barozzi (nicolaken at apache.org)
  */
+@Internal
 public abstract class POILogger {
 
     public static final int DEBUG = 1;
@@ -49,7 +50,7 @@
      * package. You need a POILogger? Go to the POILogFactory for one
      */
     POILogger() {
-        // no fields to initialise
+        // no fields to initialize
     }
 
     abstract public void initialize(String cat);
@@ -60,7 +61,7 @@
      * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
      * @param obj1 The object to log.  This is converted to a string.
      */
-    abstract public void log(int level, Object obj1);
+    abstract protected void log(int level, Object obj1);
 
     /**
      * Log a message
@@ -69,8 +70,7 @@
      * @param obj1 The object to log.  This is converted to a string.
      * @param exception An exception to be logged
      */
-    abstract public void log(int level, Object obj1,
-                    final Throwable exception);
+    abstract protected void log(int level, Object obj1, final Throwable exception);
 
 
     /**
@@ -82,602 +82,118 @@
 
    /**
      * Log a message. Lazily appends Object parameters together.
+     * If the last parameter is a {@link Throwable} it is logged specially.
      *
      * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first object to place in the message
-     * @param obj2 second object to place in the message
+     * @param objs the objects to place in the message
      */
-    public void log(int level, Object obj1, Object obj2)
-    {
-        if (check(level))
-        {
-            log(level, new StringBuffer(32).append(obj1).append(obj2));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3)
-    {
-
-
-        if (check(level))
-        {
-            log(level,
-                    new StringBuffer(48).append(obj1).append(obj2)
-                        .append(obj3));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4)
-    {
-
-
-        if (check(level))
-        {
-            log(level,
-                    new StringBuffer(64).append(obj1).append(obj2)
-                        .append(obj3).append(obj4));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5)
-    {
-
-
-        if (check(level))
-        {
-            log(level,
-                    new StringBuffer(80).append(obj1).append(obj2)
-                        .append(obj3).append(obj4).append(obj5));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6)
-    {
-
-
-        if (check(level))
-        {
-            log(level ,
-                    new StringBuffer(96).append(obj1).append(obj2)
-                        .append(obj3).append(obj4).append(obj5).append(obj6));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     * @param obj7 seventh Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6, Object obj7)
-    {
-
-
-        if (check(level))
-        {
-            log(level,
-                    new StringBuffer(112).append(obj1).append(obj2)
-                        .append(obj3).append(obj4).append(obj5).append(obj6)
-                        .append(obj7));
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third Object to place in the message
-     * @param obj4 fourth Object to place in the message
-     * @param obj5 fifth Object to place in the message
-     * @param obj6 sixth Object to place in the message
-     * @param obj7 seventh Object to place in the message
-     * @param obj8 eighth Object to place in the message
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6, Object obj7, Object obj8)
-    {
-
-
-        if (check(level))
-        {
-            log(level,
-                    new StringBuffer(128).append(obj1).append(obj2)
-                        .append(obj3).append(obj4).append(obj5).append(obj6)
-                        .append(obj7).append(obj8));
-        }
-    }
-
-    /**
-     * Log an exception, without a message
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param exception An exception to be logged
-     */
-    public void log(int level, final Throwable exception)
-    {
-        log(level, null, exception);
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(32).append(obj1).append(obj2),
-                    exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param exception An error message to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(48).append(obj1).append(obj2)
-                .append(obj3), exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4,
-                    final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(64).append(obj1).append(obj2)
-                .append(obj3).append(obj4), exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(80).append(obj1).append(obj2)
-                .append(obj3).append(obj4).append(obj5), exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6, final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level , new StringBuffer(96).append(obj1)
-                .append(obj2).append(obj3).append(obj4).append(obj5)
-                .append(obj6), exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param obj7 seventh object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6, Object obj7,
-                    final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(112).append(obj1).append(obj2)
-                .append(obj3).append(obj4).append(obj5).append(obj6)
-                .append(obj7), exception);
-        }
-    }
-
-    /**
-     * Log a message. Lazily appends Object parameters together.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param obj1 first Object to place in the message
-     * @param obj2 second Object to place in the message
-     * @param obj3 third object to place in the message
-     * @param obj4 fourth object to place in the message
-     * @param obj5 fifth object to place in the message
-     * @param obj6 sixth object to place in the message
-     * @param obj7 seventh object to place in the message
-     * @param obj8 eighth object to place in the message
-     * @param exception An exception to be logged
-     */
-    public void log(int level, Object obj1, Object obj2,
-                    Object obj3, Object obj4, Object obj5,
-                    Object obj6, Object obj7, Object obj8,
-                    final Throwable exception)
-    {
-
-
-        if (check(level))
-        {
-            log(level, new StringBuffer(128).append(obj1).append(obj2)
-                .append(obj3).append(obj4).append(obj5).append(obj6)
-                .append(obj7).append(obj8), exception);
-        }
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     */
-    public void logFormatted(int level, String message,
-                             Object obj1)
-    {
-        commonLogFormatted(level, message, new Object[]
-        {
-            obj1
-        });
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     */
-    public void logFormatted(int level, String message,
-                             Object obj1, Object obj2)
-    {
-        commonLogFormatted(level, message, new Object[]
-        {
-            obj1, obj2
-        });
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     * @param obj3 The third object to match against.
-     */
-    public void logFormatted(int level, String message,
-                             Object obj1, Object obj2,
-                             Object obj3)
-    {
-        commonLogFormatted(level, message, new Object[]
-        {
-            obj1, obj2, obj3
-        });
-    }
-
-    /**
-     * Logs a formated message. The message itself may contain %
-     * characters as place holders. This routine will attempt to match
-     * the placeholder by looking at the type of parameter passed to
-     * obj1.<p>
-     *
-     * If the parameter is an array, it traverses the array first and
-     * matches parameters sequentially against the array items.
-     * Otherwise the parameters after <code>message</code> are matched
-     * in order.<p>
-     *
-     * If the place holder matches against a number it is printed as a
-     * whole number. This can be overridden by specifying a precision
-     * in the form %n.m where n is the padding for the whole part and
-     * m is the number of decimal places to display. n can be excluded
-     * if desired. n and m may not be more than 9.<p>
-     *
-     * If the last parameter (after flattening) is a Throwable it is
-     * logged specially.
-     *
-     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
-     * @param message The message to log.
-     * @param obj1 The first object to match against.
-     * @param obj2 The second object to match against.
-     * @param obj3 The third object to match against.
-     * @param obj4 The forth object to match against.
-     */
-    public void logFormatted(int level, String message,
-                             Object obj1, Object obj2,
-                             Object obj3, Object obj4)
-    {
-        commonLogFormatted(level, message, new Object[]
-        {
-            obj1, obj2, obj3, obj4
-        });
-    }
-
-    private void commonLogFormatted(int level, String message,
-                                    Object [] unflatParams)
-    {
-
-
-        if (check(level))
-        {
-            Object[] params = flattenArrays(unflatParams);
-
-            if (params[ params.length - 1 ] instanceof Throwable)
-            {
-                log(level, StringUtil.format(message, params),
-                    ( Throwable ) params[ params.length - 1 ]);
-            }
-            else
-            {
-                log(level, StringUtil.format(message, params));
+    public void log(int level, Object... objs) {
+        if (!check(level)) return;
+        StringBuilder sb = new StringBuilder(32);
+        Throwable lastEx = null;
+        for (int i=0; i<objs.length; i++) {
+            if (i == objs.length-1 && objs[i] instanceof Throwable) {
+                lastEx = (Throwable)objs[i];
+            } else {
+                sb.append(objs[i]);
             }
         }
+        
+        String msg = sb.toString();
+        msg = msg.replaceAll("[\r\n]+", " ");  // log forging escape
+        
+        // somehow this ambiguity works and doesn't lead to a loop,
+        // but it's confusing ...
+        if (lastEx == null) {
+            log(level, msg);
+        } else {
+            log(level, msg, lastEx);
+        }
     }
 
     /**
-     * Flattens any contained objects. Only tranverses one level deep.
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param unflatParams The objects to match against.
      */
-    private Object [] flattenArrays(Object [] objects)
-    {
+    public void logFormatted(int level, String message, Object... unflatParams) {
+        if (!check(level)) return;
+        Object[] params = flattenArrays(unflatParams);
+        String msg = StringUtil.format(message, params);
+        msg = msg.replaceAll("[\r\n]+", " "); // log forging escape
+
+        if (params.length > 0 && params[params.length-1] instanceof Throwable) {
+            log(level, msg, (Throwable)params[params.length-1]);
+        } else {
+            log(level, msg);
+        }
+    }
+
+    /**
+     * Flattens any contained objects. Only traverses one level deep.
+     */
+    private Object[] flattenArrays(Object... unflatParams) {
         List<Object> results = new ArrayList<Object>();
-
-        for (int i = 0; i < objects.length; i++)
-        {
-            results.addAll(objectToObjectArray(objects[ i ]));
+        for (Object obj : unflatParams) {
+            flattenObject(results, obj);
         }
-        return results.toArray(new Object[ results.size() ]);
+        return results.toArray(new Object[results.size()]);
     }
 
-    private List<Object> objectToObjectArray(Object object)
-    {
-        List<Object> results = new ArrayList<Object>();
-
-        if (object instanceof byte [])
-        {
-            byte[] array = ( byte [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(Byte.valueOf(array[ j ]));
+    private void flattenObject(List<Object> results, Object object) {
+        if (object instanceof byte[]) {
+            for (byte b : (byte[])object) {
+                results.add(Byte.valueOf(b));
             }
-        }
-        if (object instanceof char [])
-        {
-            char[] array = ( char [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(Character.valueOf(array[ j ]));
+        } else if (object instanceof char[]) {
+            for (char c : (char[])object) {
+                results.add(Character.valueOf(c));
             }
-        }
-        else if (object instanceof short [])
-        {
-            short[] array = ( short [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(Short.valueOf(array[ j ]));
+        } else if (object instanceof short[]) {
+            for (short s : (short[])object) {
+                results.add(Short.valueOf(s));
             }
-        }
-        else if (object instanceof int [])
-        {
-            int[] array = ( int [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(Integer.valueOf(array[ j ]));
+        } else if (object instanceof int[]) {
+            for (int i : (int[])object) {
+                results.add(Integer.valueOf(i));
             }
-        }
-        else if (object instanceof long [])
-        {
-            long[] array = ( long [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(Long.valueOf(array[ j ]));
+        } else if (object instanceof long[]) {
+            for (long l : (long[])object) {
+                results.add(Long.valueOf(l));
             }
-        }
-        else if (object instanceof float [])
-        {
-            float[] array = ( float [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(new Float(array[ j ]));
+        } else if (object instanceof float[]) {
+            for (float f : (float[])object) {
+                results.add(Float.valueOf(f));
             }
-        }
-        else if (object instanceof double [])
-        {
-            double[] array = ( double [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(new Double(array[ j ]));
+        } else if (object instanceof double[]) {
+            for (double d : (double[])object) {
+                results.add(Double.valueOf(d));
             }
-        }
-        else if (object instanceof Object [])
-        {
-            Object[] array = ( Object [] ) object;
-
-            for (int j = 0; j < array.length; j++)
-            {
-                results.add(array[ j ]);
+        } else if (object instanceof Object[]) {
+            for (Object o : (Object[])object) {
+                results.add(o);
             }
-        }
-        else
-        {
+        } else {
             results.add(object);
         }
-        return results;
     }
 }
diff --git a/src/java/org/apache/poi/util/StringUtil.java b/src/java/org/apache/poi/util/StringUtil.java
index 99880f5..bd41796 100644
--- a/src/java/org/apache/poi/util/StringUtil.java
+++ b/src/java/org/apache/poi/util/StringUtil.java
@@ -22,6 +22,7 @@
 import java.text.NumberFormat;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map;
 
 import org.apache.poi.hssf.record.RecordInputStream;
@@ -310,7 +311,7 @@
 		Number number,
 		String formatting,
 		StringBuffer outputTo) {
-		NumberFormat numberFormat = NumberFormat.getInstance();
+		NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
 		if ((0 < formatting.length())
 			&& Character.isDigit(formatting.charAt(0))) {
 			numberFormat.setMinimumIntegerDigits(
diff --git a/src/scratchpad/src/org/apache/poi/wp/usermodel/CharacterRun.java b/src/java/org/apache/poi/wp/usermodel/CharacterRun.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/wp/usermodel/CharacterRun.java
rename to src/java/org/apache/poi/wp/usermodel/CharacterRun.java
diff --git a/src/scratchpad/src/org/apache/poi/wp/usermodel/Paragraph.java b/src/java/org/apache/poi/wp/usermodel/Paragraph.java
similarity index 100%
rename from src/scratchpad/src/org/apache/poi/wp/usermodel/Paragraph.java
rename to src/java/org/apache/poi/wp/usermodel/Paragraph.java
diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java
index bf241f8..0e18ee1 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java
@@ -16,6 +16,7 @@
 ==================================================================== */
 package org.apache.poi;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -37,7 +38,7 @@
 import org.apache.poi.util.IOUtils;
 import org.apache.xmlbeans.impl.common.SystemCache;
 
-public abstract class POIXMLDocument extends POIXMLDocumentPart{
+public abstract class POIXMLDocument extends POIXMLDocumentPart implements Closeable {
     public static final String DOCUMENT_CREATOR = "Apache POI";
 
     // OLE embeddings relation name
@@ -171,7 +172,7 @@
      * Closes the underlying {@link OPCPackage} from which this
      *  document was read, if there is one
      */
-    protected void close() throws IOException {
+    public void close() throws IOException {
         if (pkg != null) {
             if (pkg.getPackageAccess() == PackageAccess.READ) {
                 pkg.revert();
diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
index 24b4af2..f051eb3 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
@@ -94,6 +94,15 @@
      */
     public POIXMLDocumentPart(OPCPackage pkg) {
         PackageRelationship coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);
+        if (coreRel == null) {
+            coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0);
+            if (coreRel != null) {
+                throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699");
+            }
+        }
+        if (coreRel == null) {
+            throw new POIXMLException("OOXML file structure broken/invalid - no core document found!");
+        }
 
         this.packagePart = pkg.getPart(coreRel);
         this.packageRel = coreRel;
@@ -349,11 +358,27 @@
      * @param descriptor the part descriptor
      * @param factory the factory that will create an instance of the requested relation
      * @return the created child POIXMLDocumentPart
+     * @throws PartAlreadyExistsException
+     *             If rule M1.12 is not verified : Packages shall not contain
+     *             equivalent part names and package implementers shall neither
+     *             create nor recognize packages with equivalent part names.
      */
     public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
         return createRelationship(descriptor, factory, -1, false);
     }
 
+    /**
+     * Create a new child POIXMLDocumentPart
+     *
+     * @param descriptor the part descriptor
+     * @param factory the factory that will create an instance of the requested relation
+     * @param idx part number
+     * @return the created child POIXMLDocumentPart
+     * @throws PartAlreadyExistsException
+     *             If rule M1.12 is not verified : Packages shall not contain
+     *             equivalent part names and package implementers shall neither
+     *             create nor recognize packages with equivalent part names.
+     */
     public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
         return createRelationship(descriptor, factory, idx, false);
     }
@@ -366,6 +391,10 @@
      * @param idx part number
      * @param noRelation if true, then no relationship is added.
      * @return the created child POIXMLDocumentPart
+     * @throws PartAlreadyExistsException
+     *             If rule M1.12 is not verified : Packages shall not contain
+     *             equivalent part names and package implementers shall neither
+     *             create nor recognize packages with equivalent part names.
      */
     protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
         try {
diff --git a/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java b/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java
index ce57643..8a35a34 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java
@@ -67,9 +67,14 @@
 	 * Returns the core document properties, eg author
 	 */
 	public String getCorePropertiesText() {
+	    POIXMLDocument document = getDocument();
+        if(document == null) {  // event based extractor does not have a document
+            return "";
+        }
+
 		StringBuffer text = new StringBuffer();
-		PackagePropertiesPart props =
-			getDocument().getProperties().getCoreProperties().getUnderlyingProperties();
+        PackagePropertiesPart props =
+			document.getProperties().getCoreProperties().getUnderlyingProperties();
 
 		appendIfPresent(text, "Category", props.getCategoryProperty().getValue());
 		appendIfPresent(text, "Category", props.getCategoryProperty().getValue());
@@ -99,9 +104,14 @@
 	 *  application
 	 */
 	public String getExtendedPropertiesText() {
+        POIXMLDocument document = getDocument();
+        if(document == null) {  // event based extractor does not have a document
+            return "";
+        }
+
 		StringBuffer text = new StringBuffer();
 		org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties
-			props = getDocument().getProperties().getExtendedProperties().getUnderlyingProperties();
+			props = document.getProperties().getExtendedProperties().getUnderlyingProperties();
 
 		appendIfPresent(text, "Application", props.getApplication());
 		appendIfPresent(text, "AppVersion", props.getAppVersion());
@@ -127,9 +137,14 @@
     */
    @SuppressWarnings("deprecation")
    public String getCustomPropertiesText() {
+       POIXMLDocument document = getDocument();
+       if(document == null) {  // event based extractor does not have a document
+           return "";
+       }
+
       StringBuilder text = new StringBuilder();
       org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
-      props = getDocument().getProperties().getCustomProperties().getUnderlyingProperties();
+      props = document.getProperties().getCustomProperties().getUnderlyingProperties();
 
        for(CTProperty property : props.getPropertyArray()) {
          String val = "(not implemented!)";
diff --git a/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java b/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java
index 3a600f4..705bf42 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLTextExtractor.java
@@ -32,8 +32,6 @@
 	 * Creates a new text extractor for the given document
 	 */
 	public POIXMLTextExtractor(POIXMLDocument document) {
-		super((POIDocument)null);
-
 		_document = document;
 	}
 
diff --git a/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java b/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java
index aab8112..a05af6b 100644
--- a/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java
+++ b/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java
@@ -18,7 +18,6 @@
 

 import java.io.BufferedOutputStream;

 import java.io.File;

-import java.io.FileNotFoundException;

 import java.io.FileOutputStream;

 import java.io.IOException;

 import java.io.OutputStream;

@@ -40,9 +39,10 @@
 import javax.xml.transform.dom.DOMSource;

 import javax.xml.transform.stream.StreamResult;

 

+import org.apache.poi.openxml4j.opc.internal.ZipHelper;

+import org.apache.poi.util.IOUtils;

 import org.w3c.dom.Document;

 import org.xml.sax.InputSource;

-import org.xml.sax.SAXException;

 

 /**

  * Reads a zipped OOXML file and produces a copy with the included 

@@ -80,11 +80,10 @@
 	}

 

     private static void handleFile(File file, File outFile) throws ZipException,

-            IOException, FileNotFoundException, SAXException,

-            TransformerException, ParserConfigurationException {

+            IOException, TransformerException, ParserConfigurationException {

         System.out.println("Reading zip-file " + file + " and writing pretty-printed XML to " + outFile);

 

-        ZipFile zipFile = new ZipFile(file);

+        ZipFile zipFile = ZipHelper.openZipFile(file);

 		try {

 		    ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));

 		    try {

@@ -99,15 +98,24 @@
 		}

     }

 

-	private void handle(ZipFile file, ZipOutputStream out) throws SAXException, IOException, TransformerException {

+	private void handle(ZipFile file, ZipOutputStream out) throws IOException, TransformerException {

         Enumeration<? extends ZipEntry> entries = file.entries();

         while(entries.hasMoreElements()) {

             ZipEntry entry = entries.nextElement();

 

-            out.putNextEntry(new ZipEntry(entry.getName()));

+            String name = entry.getName();

+            out.putNextEntry(new ZipEntry(name));

             try {

-                Document document = documentBuilder.parse(new InputSource(file.getInputStream(entry)));

-                pretty(document, out, 2);

+                if(name.endsWith(".xml") || name.endsWith(".rels")) {

+                    Document document = documentBuilder.parse(new InputSource(file.getInputStream(entry)));

+                    document.setXmlStandalone(true);

+                    pretty(document, out, 2);

+                } else {

+                    System.out.println("Not pretty-printing non-XML file " + name);

+                    IOUtils.copy(file.getInputStream(entry), out);

+                }

+            } catch (Exception e) {

+                throw new IOException("While handling entry " + name, e);

             } finally {

                 out.closeEntry();

             }

diff --git a/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java b/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java
index 65d1e3d..2ef23d2 100644
--- a/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java
+++ b/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java
@@ -18,7 +18,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -47,10 +46,16 @@
 import org.apache.poi.openxml4j.opc.PackageAccess;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.Entry;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NotOLE2FileException;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
 import org.apache.poi.xslf.usermodel.XSLFRelation;
 import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
@@ -65,8 +70,9 @@
  *  document, and returns it.
  */
 public class ExtractorFactory {
-	public static final String CORE_DOCUMENT_REL =
-		"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
+	public static final String CORE_DOCUMENT_REL = PackageRelationshipTypes.CORE_DOCUMENT;
+	protected static final String VISIO_DOCUMENT_REL = PackageRelationshipTypes.VISIO_CORE_DOCUMENT;
+	protected static final String STRICT_DOCUMENT_REL = PackageRelationshipTypes.STRICT_CORE_DOCUMENT;
 
 
 	/** Should this thread prefer event based over usermodel based extractors? */
@@ -125,16 +131,14 @@
 	public static POITextExtractor createExtractor(File f) throws IOException, InvalidFormatException, OpenXML4JException, XmlException {
 		InputStream inp = null;
         try {
-            inp = new PushbackInputStream(
-                new FileInputStream(f), 8);
-
-            if(POIFSFileSystem.hasPOIFSHeader(inp)) {
-                return createExtractor(new POIFSFileSystem(inp));
-            }
-            if(POIXMLDocument.hasOOXMLHeader(inp)) {
+            try {
+                NPOIFSFileSystem fs = new NPOIFSFileSystem(f);
+                return createExtractor(fs);
+            } catch (OfficeXmlFileException e) {
                 return createExtractor(OPCPackage.open(f.toString(), PackageAccess.READ));
+            } catch (NotOLE2FileException ne) {
+                throw new IllegalArgumentException("Your File was neither an OLE2 file, nor an OOXML file");
             }
-            throw new IllegalArgumentException("Your File was neither an OLE2 file, nor an OOXML file");
         } finally {
             if(inp != null) inp.close();
         }
@@ -147,8 +151,8 @@
 			inp = new PushbackInputStream(inp, 8);
 		}
 
-		if(POIFSFileSystem.hasPOIFSHeader(inp)) {
-			return createExtractor(new POIFSFileSystem(inp));
+		if(NPOIFSFileSystem.hasPOIFSHeader(inp)) {
+			return createExtractor(new NPOIFSFileSystem(inp));
 		}
 		if(POIXMLDocument.hasOOXMLHeader(inp)) {
 			return createExtractor(OPCPackage.open(inp));
@@ -157,12 +161,30 @@
 	}
 
 	public static POIXMLTextExtractor createExtractor(OPCPackage pkg) throws IOException, OpenXML4JException, XmlException {
+	   // Check for the normal Office core document
        PackageRelationshipCollection core =
             pkg.getRelationshipsByType(CORE_DOCUMENT_REL);
-       if(core.size() != 1) {
-          throw new IllegalArgumentException("Invalid OOXML Package received - expected 1 core document, found " + core.size());
+       
+       // If nothing was found, try some of the other OOXML-based core types
+       if (core.size() == 0) {
+           // Could it be an OOXML-Strict one?
+           core = pkg.getRelationshipsByType(STRICT_DOCUMENT_REL);
+       }
+       if (core.size() == 0) {
+           // Could it be a visio one?
+           PackageRelationshipCollection visio =
+                   pkg.getRelationshipsByType(VISIO_DOCUMENT_REL);
+           if (visio.size() == 1) {
+               throw new IllegalArgumentException("Text extraction not supported for Visio OOXML files");
+           }
+       }
+       
+       // Should just be a single core document, complain if not
+       if (core.size() != 1) {
+           throw new IllegalArgumentException("Invalid OOXML Package received - expected 1 core document, found " + core.size());
        }
 
+       // Grab the core document part, and try to identify from that
        PackagePart corePart = pkg.getPart(core.getRelationship(0));
 
        // Is it XSSF?
@@ -190,6 +212,14 @@
           }
        }
 
+       // special handling for SlideShow-Theme-files, 
+       if(XSLFRelation.THEME_MANAGER.getContentType().equals(corePart.getContentType())) {
+           return new XSLFPowerPointExtractor(new XSLFSlideShow(pkg));
+       }
+
+       // ensure that we close the package again if there is an error opening it, however
+       // we need to revert the package to not re-write the file via close(), which is very likely not wanted for a TextExtractor!
+       pkg.revert();
        throw new IllegalArgumentException("No supported documents found in the OOXML package (found "+corePart.getContentType()+")");
 	}
 
@@ -197,23 +227,23 @@
 	   // Only ever an OLE2 one from the root of the FS
 		return (POIOLE2TextExtractor)createExtractor(fs.getRoot());
 	}
-
-    /**
-     * @deprecated Use {@link #createExtractor(DirectoryNode)} instead
-     */
-    @Deprecated
-    public static POITextExtractor createExtractor(DirectoryNode poifsDir, POIFSFileSystem fs)
-            throws IOException, InvalidFormatException, OpenXML4JException, XmlException
-    {
-        return createExtractor(poifsDir);
-    }
+    public static POIOLE2TextExtractor createExtractor(NPOIFSFileSystem fs) throws IOException, InvalidFormatException, OpenXML4JException, XmlException {
+        // Only ever an OLE2 one from the root of the FS
+         return (POIOLE2TextExtractor)createExtractor(fs.getRoot());
+     }
+    public static POIOLE2TextExtractor createExtractor(OPOIFSFileSystem fs) throws IOException, InvalidFormatException, OpenXML4JException, XmlException {
+        // Only ever an OLE2 one from the root of the FS
+         return (POIOLE2TextExtractor)createExtractor(fs.getRoot());
+     }
 
     public static POITextExtractor createExtractor(DirectoryNode poifsDir) throws IOException,
             InvalidFormatException, OpenXML4JException, XmlException
     {
         // Look for certain entries in the stream, to figure it
         // out from
-        if (poifsDir.hasEntry("Workbook")) {
+        if (poifsDir.hasEntry("Workbook") ||
+                // some XLS files have different entry-names
+                poifsDir.hasEntry("WORKBOOK") || poifsDir.hasEntry("BOOK")) {
             if (getPreferEventExtractor()) {
                 return new EventBasedExcelExtractor(poifsDir);
             }
@@ -263,10 +293,10 @@
 
 	/**
 	 * Returns an array of text extractors, one for each of
-	 *  the embeded documents in the file (if there are any).
-	 * If there are no embeded documents, you'll get back an
+	 *  the embedded documents in the file (if there are any).
+	 * If there are no embedded documents, you'll get back an
 	 *  empty array. Otherwise, you'll get one open
-	 *  {@link POITextExtractor} for each embeded file.
+	 *  {@link POITextExtractor} for each embedded file.
 	 */
 	public static POITextExtractor[] getEmbededDocsTextExtractors(POIOLE2TextExtractor ext) throws IOException, InvalidFormatException, OpenXML4JException, XmlException {
 	   // All the embded directories we spotted
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
index e210be6..ccf57a6 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
@@ -29,6 +29,7 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.Hashtable;
 import java.util.List;
@@ -581,6 +582,7 @@
 			if (part.getContentType().equals(contentType))
 				retArr.add(part);
 		}
+		Collections.sort(retArr);
 		return retArr;
 	}
 
@@ -604,22 +606,31 @@
 			    retArr.add(part);
 			}
 		}
+		Collections.sort(retArr);
 		return retArr;
 	}
 
+	/**
+	 * Retrieve parts by name
+	 *
+	 * @param namePattern
+	 *            The pattern for matching the names
+	 * @return All parts associated to the specified content type, sorted
+	 * in alphanumerically by the part-name
+	 */
 	public List<PackagePart> getPartsByName(final Pattern namePattern) {
 	    if (namePattern == null) {
 	        throw new IllegalArgumentException("name pattern must not be null");
 	    }
+	    Matcher matcher = namePattern.matcher("");
 	    ArrayList<PackagePart> result = new ArrayList<PackagePart>();
 	    for (PackagePart part : partList.values()) {
 	        PackagePartName partName = part.getPartName();
-	        String name = partName.getName();
-	        Matcher matcher = namePattern.matcher(name);
-	        if (matcher.matches()) {
+	        if (matcher.reset(partName.getName()).matches()) {
 	            result.add(part);
 	        }
 	    }
+	    Collections.sort(result);
 	    return result;
 	}
 
@@ -727,7 +738,9 @@
 				}
 			}
 		}
-		return new ArrayList<PackagePart>(partList.values());
+		ArrayList<PackagePart> result = new ArrayList<PackagePart>(partList.values());
+		java.util.Collections.sort(result);
+		return result;
 	}
 
 	/**
@@ -739,7 +752,7 @@
 	 * @param contentType
 	 *            Part content type.
 	 * @return The newly created part.
-	 * @throws InvalidFormatException
+	 * @throws PartAlreadyExistsException
 	 *             If rule M1.12 is not verified : Packages shall not contain
 	 *             equivalent part names and package implementers shall neither
 	 *             create nor recognize packages with equivalent part names.
@@ -762,7 +775,7 @@
 	 *            Specify if the existing relationship part, if any, logically
 	 *            associated to the newly created part will be loaded.
 	 * @return The newly created part.
-	 * @throws InvalidFormatException
+	 * @throws PartAlreadyExistsException
 	 *             If rule M1.12 is not verified : Packages shall not contain
 	 *             equivalent part names and package implementers shall neither
 	 *             create nor recognize packages with equivalent part names.
@@ -1409,8 +1422,11 @@
 		} catch (FileNotFoundException e) {
 			throw new IOException(e.getLocalizedMessage());
 		}
-		this.save(fos);
-		fos.close();
+		try {
+			this.save(fos);
+		} finally {
+			fos.close();
+		}
 	}
 
 	/**
@@ -1535,4 +1551,31 @@
         }
         return success;
     }
+
+    /**
+    * Add the specified part, and register its content type with the content
+    * type manager.
+    *
+    * @param part
+    *            The part to add.
+    */
+    public void registerPartAndContentType(PackagePart part) {
+        addPackagePart(part);
+        this.contentTypeManager.addContentType(part.getPartName(), part.getContentType());
+        this.isDirty = true;
+    }
+
+    /**
+     * Remove the specified part, and clear its content type from the content
+     * type manager.
+     *
+     * @param partName
+     *            The part name of the part to remove.
+     */
+    public void unregisterPartAndContentType(PackagePartName partName) {
+        removePart(partName);
+        this.contentTypeManager.removeContentType(partName);
+        this.isDirty = true;
+    }
+
 }
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
index 8b72770..8f961c9 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
@@ -30,11 +30,8 @@
 
 /**
  * Provides a base class for parts stored in a Package.
- *
- * @author Julien Chable
- * @version 0.9
  */
-public abstract class PackagePart implements RelationshipSource {
+public abstract class PackagePart implements RelationshipSource, Comparable<PackagePart> {
 
 	/**
 	 * This part's container.
@@ -228,8 +225,13 @@
 	 *            Relationship unique id.
 	 * @return The newly created and added relationship
 	 *
+	 * @throws InvalidOperationException
+	 *             If a writing operation is done on a read only package or 
+	 *             invalid nested relations are created.
 	 * @throws InvalidFormatException
 	 *             If the URI point to a relationship part URI.
+	 * @throws IllegalArgumentException if targetPartName, targetMode 
+	 *             or relationshipType are passed as null
 	 * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,
 	 *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String)
 	 */
@@ -599,11 +601,14 @@
 	 */
 	public void setContentType(String contentType)
 			throws InvalidFormatException {
-		if (_container == null)
-			this._contentType = new ContentType(contentType);
-		else
-			throw new InvalidOperationException(
-					"You can't change the content type of a part.");
+		if (_container == null) {
+			_contentType = new ContentType(contentType);
+		}
+		else {
+		    _container.unregisterPartAndContentType(_partName);
+		    _contentType = new ContentType(contentType);
+		    _container.registerPartAndContentType(this);
+		}
 	}
 
 	public OPCPackage getPackage() {
@@ -645,6 +650,19 @@
 				+ this._contentType.toString();
 	}
 
+	/**
+	 * Compare based on the package part name, using a natural sort order
+	 */
+	@Override
+	public int compareTo(PackagePart other)
+	{
+	    // NOTE could also throw a NullPointerException() if desired
+	    if (other == null)
+	        return -1;
+
+	    return PackagePartName.compare(this._partName, other._partName);
+	}
+
 	/*-------------- Abstract methods ------------- */
 
 	/**
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
index 6f946a2..9ac6941 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
@@ -17,6 +17,7 @@
 
 package org.apache.poi.openxml4j.opc;
 
+import java.math.BigInteger;
 import java.net.URI;
 import java.net.URISyntaxException;
 
@@ -428,19 +429,20 @@
 	}
 
 	/**
-	 * Compare two part name following the rule M1.12 :
+	 * Compare two part names following the rule M1.12 :
 	 *
 	 * Part name equivalence is determined by comparing part names as
 	 * case-insensitive ASCII strings. Packages shall not contain equivalent
 	 * part names and package implementers shall neither create nor recognize
 	 * packages with equivalent part names. [M1.12]
 	 */
-	public int compareTo(PackagePartName otherPartName) {
-		if (otherPartName == null)
-			return -1;
-		return this.partNameURI.toASCIIString().toLowerCase().compareTo(
-				otherPartName.partNameURI.toASCIIString().toLowerCase());
-	}
+        @Override
+        public int compareTo(PackagePartName other)
+        {
+            // compare with natural sort order
+            return compare(this, other);
+        }
+
 
 	/**
 	 * Retrieves the extension of the part name if any. If there is no extension
@@ -474,14 +476,17 @@
 	 * packages with equivalent part names. [M1.12]
 	 */
 	@Override
-	public boolean equals(Object otherPartName) {
-		if (otherPartName == null
-				|| !(otherPartName instanceof PackagePartName))
-			return false;
-		return this.partNameURI.toASCIIString().toLowerCase().equals(
-				((PackagePartName) otherPartName).partNameURI.toASCIIString()
-						.toLowerCase());
-	}
+	public boolean equals(Object other) {
+            if (other instanceof PackagePartName) {
+                // String.equals() is compatible with our compareTo(), but cheaper
+                return this.partNameURI.toASCIIString().toLowerCase().equals
+                (
+                    ((PackagePartName) other).partNameURI.toASCIIString().toLowerCase()
+                );
+            } else {
+                return false;
+            }
+        }
 
 	@Override
 	public int hashCode() {
@@ -503,4 +508,106 @@
 	public URI getURI() {
 		return this.partNameURI;
 	}
+
+
+    /**
+     * A natural sort order for package part names, consistent with the
+     * requirements of {@code java.util.Comparator}, but simply implemented
+     * as a static method.
+     * <p>
+     * For example, this sorts "file10.png" after "file2.png" (comparing the
+     * numerical portion), but sorts "File10.png" before "file2.png"
+     * (lexigraphical sort)
+     *
+     * <p>
+     * When comparing part names, the rule M1.12 is followed:
+     *
+     * Part name equivalence is determined by comparing part names as
+     * case-insensitive ASCII strings. Packages shall not contain equivalent
+     * part names and package implementers shall neither create nor recognize
+     * packages with equivalent part names. [M1.12]
+     */
+    public static int compare(PackagePartName obj1, PackagePartName obj2)
+    {
+        // NOTE could also throw a NullPointerException() if desired
+        if (obj1 == null)
+        {
+            // (null) == (null), (null) < (non-null)
+            return (obj2 == null ? 0 : -1);
+        }
+        else if (obj2 == null)
+        {
+            // (non-null) > (null)
+            return 1;
+        }
+
+        return compare
+        (
+            obj1.getURI().toASCIIString().toLowerCase(),
+            obj2.getURI().toASCIIString().toLowerCase()
+        );
+    }
+
+
+    /**
+     * A natural sort order for strings, consistent with the
+     * requirements of {@code java.util.Comparator}, but simply implemented
+     * as a static method.
+     * <p>
+     * For example, this sorts "file10.png" after "file2.png" (comparing the
+     * numerical portion), but sorts "File10.png" before "file2.png"
+     * (lexigraphical sort)
+     */
+    public static int compare(String str1, String str2)
+    {
+        if (str1 == null)
+        {
+            // (null) == (null), (null) < (non-null)
+            return (str2 == null ? 0 : -1);
+        }
+        else if (str2 == null)
+        {
+            // (non-null) > (null)
+            return 1;
+        }
+
+        int len1 = str1.length();
+        int len2 = str2.length();
+        for (int idx1 = 0, idx2 = 0; idx1 < len1 && idx2 < len2; /*nil*/)
+        {
+            char c1 = str1.charAt(idx1++);
+            char c2 = str2.charAt(idx2++);
+
+            if (Character.isDigit(c1) && Character.isDigit(c2))
+            {
+                int beg1 = idx1 - 1;  // undo previous increment
+                while (idx1 < len1 && Character.isDigit(str1.charAt(idx1)))
+                {
+                    ++idx1;
+                }
+
+                int beg2 = idx2 - 1;  // undo previous increment
+                while (idx2 < len2 && Character.isDigit(str2.charAt(idx2)))
+                {
+                    ++idx2;
+                }
+
+                // note: BigInteger for extra safety
+                int cmp = new BigInteger(str1.substring(beg1, idx1)).compareTo
+                (
+                    new BigInteger(str2.substring(beg2, idx2))
+                );
+                if (cmp != 0) return cmp;
+            }
+            else if (c1 != c2)
+            {
+                return (c1 - c2);
+            }
+        }
+
+        return (len1 - len2);
+    }
+
 }
+
+/* ************************************************************************** */
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
index 134e6a9..5d9801c 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
@@ -19,14 +19,10 @@
 
 /**
  * Relationship types.
- *
- * @author Julien Chable
- * @version 0.2
  */
 public interface PackageRelationshipTypes {
-
-	/**
-	 * Core properties relationship type.
+    /**
+     * Core properties relationship type.
      *
      *  <p>
      *  The standard specifies a source relations ship for the Core File Properties part as follows:
@@ -37,71 +33,86 @@
      *   <code>http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties.</code>
      * </p>
      * See 2.1.33 Part 1 Section 15.2.11.1, Core File Properties Part in [MS-OE376].pdf
-	 */
-	String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
+     */
+    String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
 
     /**
      * Core properties relationship type as defiend in ECMA 376.
-      */
+     */
     String CORE_PROPERTIES_ECMA376 = "http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties";
 
-	/**
-	 * Digital signature relationship type.
-	 */
-	String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
+    /**
+     * Digital signature relationship type.
+     */
+    String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
 
-	/**
-	 * Digital signature certificate relationship type.
-	 */
-	String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
+    /**
+     * Digital signature certificate relationship type.
+     */
+    String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
 
-	/**
-	 * Digital signature origin relationship type.
-	 */
-	String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
+    /**
+     * Digital signature origin relationship type.
+     */
+    String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
 
-	/**
-	 * Thumbnail relationship type.
-	 */
-	String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
+    /**
+     * Thumbnail relationship type.
+     */
+    String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
 
-	/**
-	 * Extended properties relationship type.
-	 */
-	String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
+    /**
+     * Extended properties relationship type.
+     */
+    String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
 
-	/**
-	 * Custom properties relationship type.
-	 */
-	String CUSTOM_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
-	
-	/**
-	 * Core properties relationship type.
-	 */
-	String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
+    /**
+     * Extended properties relationship type for strict ooxml.
+     */
+    String STRICT_EXTENDED_PROPERTIES = "http://purl.oclc.org/ooxml/officeDocument/relationships/extendedProperties";
 
-	/**
-	 * Custom XML relationship type.
-	 */
-	String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
+    /**
+     * Custom properties relationship type.
+     */
+    String CUSTOM_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties";
 
-	/**
-	 * Image type.
-	 */
-	String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
+    /**
+     * Core document relationship type.
+     */
+    String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
+
+    /**
+     * Core document relationship type for strict ooxml.
+     */
+    String STRICT_CORE_DOCUMENT = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
+
+    /**
+     * Custom XML relationship type.
+     */
+    String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
+
+    /**
+     * Image type.
+     */
+    String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
 
     /**
      * Hyperlink type.
      */
     String HYPERLINK_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
 
-	/**
-	 * Style type.
-	 */
-	String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
-	
-	/**
-	 * External Link to another Document
-	 */
-	String EXTERNAL_LINK_PATH = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath";
+    /**
+     * Style type.
+     */
+    String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
+
+    /**
+     * External Link to another Document
+     */
+    String EXTERNAL_LINK_PATH = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath";
+
+    /**
+     * Visio 2010 VSDX equivalent of package {@link #CORE_DOCUMENT}
+     */
+    String VISIO_CORE_DOCUMENT = "http://schemas.microsoft.com/visio/2010/relationships/document";
 }
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
index 62f26b7..8937f8e 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
@@ -41,6 +41,8 @@
 import org.apache.poi.openxml4j.util.ZipEntrySource;
 import org.apache.poi.openxml4j.util.ZipFileZipEntrySource;
 import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
+import org.apache.poi.openxml4j.util.ZipSecureFile;
+import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.TempFile;
@@ -85,9 +87,9 @@
     @SuppressWarnings("deprecation")
     ZipPackage(InputStream in, PackageAccess access) throws IOException {
     	super(access);
-    	this.zipArchive = new ZipInputStreamZipEntrySource(
-    			new ZipInputStream(in)
-    			);
+    	InputStream zis = new ZipInputStream(in);
+    	ThresholdInputStream tis = ZipSecureFile.addThreshold(zis);
+    	this.zipArchive = new ZipInputStreamZipEntrySource(tis);
     }
 
     /**
@@ -443,7 +445,9 @@
 			if (this.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).size() == 0 &&
                 this.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES_ECMA376).size() == 0    ) {
 				logger.log(POILogger.DEBUG,"Save core properties part");
-
+				
+				// Ensure that core properties are added if missing
+				getPackageProperties();
 				// Add core properties to part list ...
 				addPackagePart(this.packageProperties);
 				// ... and to add its relationship ...
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
index 9598b05..408fa41 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
@@ -29,6 +29,7 @@
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.ZipPackage;
+import org.apache.poi.openxml4j.util.ZipSecureFile;
 
 public final class ZipHelper {
 
@@ -154,7 +155,7 @@
          return null;
       }
 
-      return new ZipFile(file);
+      return new ZipSecureFile(file);
    }
 
 	/**
@@ -171,6 +172,6 @@
 			return null;
 		}
 
-		return new ZipFile(f);
+		return new ZipSecureFile(f);
 	}
 }
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java
index ca549f9..76e292b 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java
@@ -34,15 +34,11 @@
 
 /**
  * Package properties marshaller.
- *
- * @author CDubet, Julien Chable
  */
 public class PackagePropertiesMarshaller implements PartMarshaller {
-
-    
     private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI;
 	static {
-	    final XMLEventFactory f = XMLEventFactory.newFactory();
+	    final XMLEventFactory f = XMLEventFactory.newInstance();
 	    namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
 	    namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
 	    namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
index f7f334c..7d72212 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
@@ -26,6 +26,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream;
+
 /**
  * Provides a way to get at all the ZipEntries
  *  from a ZipInputStream, as many times as required.
@@ -43,7 +45,7 @@
 	 * We'll then eat lots of memory, but be able to
 	 *  work with the entries at-will.
 	 */
-	public ZipInputStreamZipEntrySource(ZipInputStream inp) throws IOException {
+	public ZipInputStreamZipEntrySource(ThresholdInputStream inp) throws IOException {
 		zipEntries = new ArrayList<FakeZipEntry>();
 		
 		boolean going = true;
@@ -105,7 +107,7 @@
 	public static class FakeZipEntry extends ZipEntry {
 		private byte[] data;
 		
-		public FakeZipEntry(ZipEntry entry, ZipInputStream inp) throws IOException {
+		public FakeZipEntry(ZipEntry entry, InputStream inp) throws IOException {
 			super(entry.getName());
 			
 			// Grab the de-compressed contents for later
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java
new file mode 100644
index 0000000..60b31ee
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java
@@ -0,0 +1,215 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+

+package org.apache.poi.openxml4j.util;

+

+import java.io.File;

+import java.io.FilterInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PushbackInputStream;

+import java.lang.reflect.Field;

+import java.nio.charset.Charset;

+import java.util.zip.InflaterInputStream;

+import java.util.zip.ZipEntry;

+import java.util.zip.ZipException;

+import java.util.zip.ZipFile;

+import java.util.zip.ZipInputStream;

+

+import org.apache.poi.util.POILogFactory;

+import org.apache.poi.util.POILogger;

+

+/**

+ * This class wraps a {@link ZipFile} in order to check the

+ * entries for <a href="https://en.wikipedia.org/wiki/Zip_bomb">zip bombs</a>

+ * while reading the archive.

+ * If a {@link ZipInputStream} is directly used, the wrapper

+ * can be applied via {@link #addThreshold(InputStream)}.

+ * The alert limits can be globally defined via {@link #setMaxEntrySize(long)}

+ * and {@link #setMinInflateRatio(double)}.

+ */

+public class ZipSecureFile extends ZipFile {

+    private static POILogger logger = POILogFactory.getLogger(ZipSecureFile.class);

+    

+    private static double MIN_INFLATE_RATIO = 0.01d;

+    private static long MAX_ENTRY_SIZE = 0xFFFFFFFFl;

+

+    /**

+     * Sets the ratio between de- and inflated bytes to detect zipbomb.

+     * It defaults to 1% (= 0.01d), i.e. when the compression is better than

+     * 1% for any given read package part, the parsing will fail

+     *

+     * @param ratio the ratio between de- and inflated bytes to detect zipbomb

+     */

+    public static void setMinInflateRatio(double ratio) {

+        MIN_INFLATE_RATIO = ratio;

+    }

+

+    /**

+     * Sets the maximum file size of a single zip entry. It defaults to 4GB,

+     * i.e. the 32-bit zip format maximum.

+     *

+     * @param maxEntrySize the max. file size of a single zip entry

+     */

+    public static void setMaxEntrySize(long maxEntrySize) {

+        if (maxEntrySize < 0 || maxEntrySize > 0xFFFFFFFFl) {

+            throw new IllegalArgumentException("Max entry size is bounded [0-4GB].");

+        }

+        MAX_ENTRY_SIZE = maxEntrySize;

+    }

+

+    public ZipSecureFile(File file, int mode) throws IOException {

+        super(file, mode);

+    }

+

+    public ZipSecureFile(File file) throws ZipException, IOException {

+        super(file);

+    }

+

+    public ZipSecureFile(String name) throws IOException {

+        super(name);

+    }

+

+    /**

+     * Returns an input stream for reading the contents of the specified

+     * zip file entry.

+     *

+     * <p> Closing this ZIP file will, in turn, close all input

+     * streams that have been returned by invocations of this method.

+     *

+     * @param entry the zip file entry

+     * @return the input stream for reading the contents of the specified

+     * zip file entry.

+     * @throws ZipException if a ZIP format error has occurred

+     * @throws IOException if an I/O error has occurred

+     * @throws IllegalStateException if the zip file has been closed

+     */

+    public InputStream getInputStream(ZipEntry entry) throws IOException {

+        InputStream zipIS = super.getInputStream(entry);

+        return addThreshold(zipIS);

+    }

+

+    public static ThresholdInputStream addThreshold(InputStream zipIS) throws IOException {

+        ThresholdInputStream newInner;

+        if (zipIS instanceof InflaterInputStream) {

+            try {

+                Field f = FilterInputStream.class.getDeclaredField("in");

+                f.setAccessible(true);

+                InputStream oldInner = (InputStream)f.get(zipIS);

+                newInner = new ThresholdInputStream(oldInner, null);

+                f.set(zipIS, newInner);

+            } catch (Exception ex) {

+                logger.log(POILogger.WARN, "SecurityManager doesn't allow manipulation via reflection for zipbomb detection - continue with original input stream", ex);

+                newInner = null;

+            }

+        } else {

+            // the inner stream is a ZipFileInputStream, i.e. the data wasn't compressed

+            newInner = null;

+        }

+

+        return new ThresholdInputStream(zipIS, newInner);

+    }

+

+    public static class ThresholdInputStream extends PushbackInputStream {

+        long counter = 0;

+        ThresholdInputStream cis;

+

+        public ThresholdInputStream(InputStream is, ThresholdInputStream cis) {

+            super(is,1);

+            this.cis = cis;

+        }

+

+        public int read() throws IOException {

+            int b = in.read();

+            if (b > -1) advance(1);

+            return b;

+        }

+

+        public int read(byte b[], int off, int len) throws IOException {

+            int cnt = in.read(b, off, len);

+            if (cnt > -1) advance(cnt);

+            return cnt;

+

+        }

+

+        public long skip(long n) throws IOException {

+            counter = 0;

+            return in.skip(n);

+        }

+

+        public synchronized void reset() throws IOException {

+            counter = 0;

+            in.reset();

+        }

+

+        public void advance(int advance) throws IOException {

+            counter += advance;

+            // check the file size first, in case we are working on uncompressed streams

+            if (counter < MAX_ENTRY_SIZE) {

+                if (cis == null) return;

+                double ratio = (double)cis.counter/(double)counter;

+                if (ratio > MIN_INFLATE_RATIO) return;

+            }

+            throw new IOException("Zip bomb detected! Exiting.");

+        }

+

+        public ZipEntry getNextEntry() throws IOException {

+            if (!(in instanceof ZipInputStream)) {

+                throw new UnsupportedOperationException("underlying stream is not a ZipInputStream");

+            }

+            counter = 0;

+            return ((ZipInputStream)in).getNextEntry();

+        }

+

+        public void closeEntry() throws IOException {

+            if (!(in instanceof ZipInputStream)) {

+                throw new UnsupportedOperationException("underlying stream is not a ZipInputStream");

+            }

+            counter = 0;

+            ((ZipInputStream)in).closeEntry();

+        }

+

+        public void unread(int b) throws IOException {

+            if (!(in instanceof PushbackInputStream)) {

+                throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream");

+            }

+            if (--counter < 0) counter = 0;

+            ((PushbackInputStream)in).unread(b);

+        }

+

+        public void unread(byte[] b, int off, int len) throws IOException {

+            if (!(in instanceof PushbackInputStream)) {

+                throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream");

+            }

+            counter -= len;

+            if (--counter < 0) counter = 0;

+            ((PushbackInputStream)in).unread(b, off, len);

+        }

+

+        public int available() throws IOException {

+            return in.available();

+        }

+

+        public boolean markSupported() {

+            return in.markSupported();

+        }

+

+        public synchronized void mark(int readlimit) {

+            in.mark(readlimit);

+        }

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java
index 0549968..3af7812 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java
@@ -279,7 +279,7 @@
     }
 
     public InputStream getDataStream(DirectoryNode dir) throws IOException, GeneralSecurityException {
-        DocumentInputStream dis = dir.createDocumentInputStream("EncryptedPackage");
+        DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY);
         _length = dis.readLong();
         
         ChunkedCipherInputStream cipherStream = new AgileCipherInputStream(dis, _length);
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
index 51ced4c..c6d3072 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
@@ -33,6 +33,7 @@
 import java.io.File;

 import java.io.FileInputStream;

 import java.io.IOException;

+import java.io.InputStream;

 import java.io.OutputStream;

 import java.security.GeneralSecurityException;

 import java.security.MessageDigest;

@@ -242,12 +243,15 @@
         LittleEndian.putLong(buf, 0, oleStreamSize);

         integrityMD.update(buf, 0, LittleEndian.LONG_SIZE);

         

-        FileInputStream fis = new FileInputStream(tmpFile);

-        int readBytes;

-        while ((readBytes = fis.read(buf)) != -1) {

-            integrityMD.update(buf, 0, readBytes);

+        InputStream fis = new FileInputStream(tmpFile);

+        try {

+            int readBytes;

+            while ((readBytes = fis.read(buf)) != -1) {

+                integrityMD.update(buf, 0, readBytes);

+            }

+        } finally {

+        	fis.close();

         }

-        fis.close();

         

         byte hmacValue[] = integrityMD.doFinal();

         

diff --git a/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
index de847fd..dfdf3f9 100644
--- a/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
+++ b/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
@@ -21,106 +21,279 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PushbackInputStream;
+import java.security.GeneralSecurityException;
 
+import org.apache.poi.EmptyFileException;
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageAccess;
+import org.apache.poi.poifs.crypt.Decryptor;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * Factory for creating the appropriate kind of Workbook
- *  (be it {@link HSSFWorkbook} or {@link XSSFWorkbook}), 
+ *  (be it {@link HSSFWorkbook} or {@link XSSFWorkbook}),
  *  by auto-detecting from the supplied input.
  */
 public class WorkbookFactory {
     /**
      * Creates a HSSFWorkbook from the given POIFSFileSystem
-     * <p>Note that in order to properly release resources the 
+     * <p>Note that in order to properly release resources the
      *  Workbook should be closed after use.
      */
     public static Workbook create(POIFSFileSystem fs) throws IOException {
         return new HSSFWorkbook(fs);
     }
-    
+
     /**
      * Creates a HSSFWorkbook from the given NPOIFSFileSystem
-     * <p>Note that in order to properly release resources the 
+     * <p>Note that in order to properly release resources the
      *  Workbook should be closed after use.
      */
     public static Workbook create(NPOIFSFileSystem fs) throws IOException {
-        return new HSSFWorkbook(fs.getRoot(), true);
+        try {
+            return create(fs, null);
+        } catch (InvalidFormatException e) {
+            // Special case of OOXML-in-POIFS which is broken
+            throw new IOException(e);
+        }
     }
-    
+
+    /**
+     * Creates a Workbook from the given NPOIFSFileSystem, which may
+     *  be password protected
+     *
+     *  @param fs The {@link NPOIFSFileSystem} to read the document from
+     *  @param password The password that should be used or null if no password is necessary.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     */
+    private static Workbook create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException {
+        DirectoryNode root = fs.getRoot();
+
+        // Encrypted OOXML files go inside OLE2 containers, is this one?
+        if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
+            EncryptionInfo info = new EncryptionInfo(fs);
+            Decryptor d = Decryptor.getInstance(info);
+
+            boolean passwordCorrect = false;
+            InputStream stream = null;
+            try {
+                if (password != null && d.verifyPassword(password)) {
+                    passwordCorrect = true;
+                }
+                if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
+                    passwordCorrect = true;
+                }
+                if (passwordCorrect) {
+                    stream = d.getDataStream(root);
+                }
+            } catch (GeneralSecurityException e) {
+                throw new IOException(e);
+            }
+
+            if (! passwordCorrect) {
+                if (password != null)
+                    throw new EncryptedDocumentException("Password incorrect");
+                else
+                    throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied");
+            }
+
+            OPCPackage pkg = OPCPackage.open(stream);
+            return create(pkg);
+        }
+
+        // If we get here, it isn't an encrypted XLSX file
+        // So, treat it as a regular HSSF XLS one
+        if (password != null) {
+            Biff8EncryptionKey.setCurrentUserPassword(password);
+        }
+        Workbook wb = new HSSFWorkbook(root, true);
+        Biff8EncryptionKey.setCurrentUserPassword(null);
+        return wb;
+    }
+
     /**
      * Creates a XSSFWorkbook from the given OOXML Package
-     * <p>Note that in order to properly release resources the 
-     *  Workbook should be closed after use.
+     *
+     * <p>Note that in order to properly release resources the
+     *  Workbook should be closed after use.</p>
+     *
+     *  @param pkg The {@link OPCPackage} opened for reading data.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
      */
     public static Workbook create(OPCPackage pkg) throws IOException {
         return new XSSFWorkbook(pkg);
     }
-    
+
     /**
      * Creates the appropriate HSSFWorkbook / XSSFWorkbook from
      *  the given InputStream.
+     *
      * <p>Your input stream MUST either support mark/reset, or
-     *  be wrapped as a {@link PushbackInputStream}! Note that 
-     *  using an {@link InputStream} has a higher memory footprint 
-     *  than using a {@link File}.</p> 
-     * <p>Note that in order to properly release resources the 
-     *  Workbook should be closed after use.
+     *  be wrapped as a {@link PushbackInputStream}! Note that
+     *  using an {@link InputStream} has a higher memory footprint
+     *  than using a {@link File}.</p>
+     *
+     * <p>Note that in order to properly release resources the
+     *  Workbook should be closed after use. Note also that loading
+     *  from an InputStream requires more memory than loading
+     *  from a File, so prefer {@link #create(File)} where possible.
+     *
+     *  @param inp The {@link InputStream} to read data from.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     *  @throws EncryptedDocumentException If the workbook given is password protected
      */
-    public static Workbook create(InputStream inp) throws IOException, InvalidFormatException {
+    public static Workbook create(InputStream inp) throws IOException, InvalidFormatException, EncryptedDocumentException {
+        return create(inp, null);
+    }
+
+    /**
+     * Creates the appropriate HSSFWorkbook / XSSFWorkbook from
+     *  the given InputStream, which may be password protected.
+     * <p>Your input stream MUST either support mark/reset, or
+     *  be wrapped as a {@link PushbackInputStream}! Note that
+     *  using an {@link InputStream} has a higher memory footprint
+     *  than using a {@link File}.</p>
+     *
+     * <p>Note that in order to properly release resources the
+     *  Workbook should be closed after use. Note also that loading
+     *  from an InputStream requires more memory than loading
+     *  from a File, so prefer {@link #create(File)} where possible.</p>
+     *
+     *  @param inp The {@link InputStream} to read data from.
+     *  @param password The password that should be used or null if no password is necessary.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static Workbook create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
         // If clearly doesn't do mark/reset, wrap up
         if (! inp.markSupported()) {
             inp = new PushbackInputStream(inp, 8);
         }
 
-        if (POIFSFileSystem.hasPOIFSHeader(inp)) {
-            return new HSSFWorkbook(inp);
+        // Ensure that there is at least some data there
+        byte[] header8 = IOUtils.peekFirst8Bytes(inp);
+
+        // Try to create
+        if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
+            return create(fs, password);
         }
         if (POIXMLDocument.hasOOXMLHeader(inp)) {
             return new XSSFWorkbook(OPCPackage.open(inp));
         }
         throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
     }
-    
+
     /**
      * Creates the appropriate HSSFWorkbook / XSSFWorkbook from
      *  the given File, which must exist and be readable.
-     * <p>Note that in order to properly release resources the 
+     * <p>Note that in order to properly release resources the
      *  Workbook should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     *  @throws EncryptedDocumentException If the workbook given is password protected
      */
-    public static Workbook create(File file) throws IOException, InvalidFormatException {
+    public static Workbook create(File file) throws IOException, InvalidFormatException, EncryptedDocumentException {
+        return create(file, null);
+    }
+
+    /**
+     * Creates the appropriate HSSFWorkbook / XSSFWorkbook from
+     *  the given File, which must exist and be readable, and
+     *  may be password protected
+     * <p>Note that in order to properly release resources the
+     *  Workbook should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *  @param password The password that should be used or null if no password is necessary.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static Workbook create(File file, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
+    	return create(file, password, false);
+    }
+
+    /**
+     * Creates the appropriate HSSFWorkbook / XSSFWorkbook from
+     *  the given File, which must exist and be readable, and
+     *  may be password protected
+     * <p>Note that in order to properly release resources the
+     *  Workbook should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *  @param password The password that should be used or null if no password is necessary.
+     *  @param readOnly If the Workbook should be opened in read-only mode to avoid writing back
+     *  	changes when the document is closed.
+     *
+     *  @return The created Workbook
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link Workbook}
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static Workbook create(File file, String password, boolean readOnly) throws IOException, InvalidFormatException, EncryptedDocumentException {
         if (! file.exists()) {
             throw new FileNotFoundException(file.toString());
         }
 
         try {
-            @SuppressWarnings("resource")
-            NPOIFSFileSystem fs = new NPOIFSFileSystem(file);
-            return new HSSFWorkbook(fs.getRoot(), true);
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly);
+            return create(fs, password);
         } catch(OfficeXmlFileException e) {
             // opening as .xls failed => try opening as .xlsx
-            OPCPackage pkg = OPCPackage.open(file);
+            OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);
             try {
                 return new XSSFWorkbook(pkg);
             } catch (IOException ioe) {
                 // ensure that file handles are closed (use revert() to not re-write the file)
                 pkg.revert();
                 //pkg.close();
-                
+
                 // rethrow exception
                 throw ioe;
             } catch (IllegalArgumentException ioe) {
-                // ensure that file handles are closed (use revert() to not re-write the file) 
+                // ensure that file handles are closed (use revert() to not re-write the file)
                 pkg.revert();
                 //pkg.close();
-                
+
                 // rethrow exception
                 throw ioe;
             }
diff --git a/src/ooxml/java/org/apache/poi/util/OOXMLLite.java b/src/ooxml/java/org/apache/poi/util/OOXMLLite.java
index 3b8dc32..0503dfa 100644
--- a/src/ooxml/java/org/apache/poi/util/OOXMLLite.java
+++ b/src/ooxml/java/org/apache/poi/util/OOXMLLite.java
@@ -32,14 +32,12 @@
 import java.util.Vector;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
-import java.util.regex.Pattern;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-import org.junit.internal.TextListener;
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Result;
+import java.util.regex.Pattern;

+

+import junit.framework.TestCase;

+import org.junit.Test;

+import org.junit.internal.TextListener;

+import org.junit.runner.JUnitCore;import org.junit.runner.Result;
 
 /**
  * Build a 'lite' version of the ooxml-schemas.jar
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java
index 6e26335..7153bc8 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRenderer.java
@@ -99,6 +99,10 @@
         } catch (Exception e) {

             return false;

         }

+        

+        if(img == null) {

+        	return false;

+        }

 

         int iw = img.getWidth();

 		int ih = img.getHeight();

diff --git a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java
index 7e449da..a3e04eb 100644
--- a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java
+++ b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java
@@ -19,13 +19,13 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Enumeration;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import org.apache.poi.openxml4j.opc.internal.ZipHelper;
+import org.apache.poi.util.IOUtils;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
 
@@ -39,8 +39,12 @@
     public static void main(String[] args) throws Exception {
         for (int i = 0; i < args.length; i++) {
             System.out.println("Dumping " + args[i]);
-            ZipFile zip = new ZipFile(args[i]);
-            dump(zip);
+            ZipFile zip = ZipHelper.openZipFile(args[i]);
+            try {
+            	dump(zip);
+            } finally {
+            	zip.close();
+            }
         }
     }
 
@@ -49,6 +53,7 @@
         int sep = zipname.lastIndexOf('.');
         File root = new File(zipname.substring(0, sep));
         root.mkdir();
+        System.out.println("Dupming to directory " + root);
 
         Enumeration<? extends ZipEntry> en = zip.entries();
         while(en.hasMoreElements()){
@@ -61,30 +66,24 @@
             }
 
             File f = new File(root, entry.getName());
-            FileOutputStream out = new FileOutputStream(f);
-
-            if(entry.getName().endsWith(".xml") || entry.getName().endsWith(".vml") || entry.getName().endsWith(".rels")){
-                try {
-                    XmlObject xml = XmlObject.Factory.parse(zip.getInputStream(entry));
-                    XmlOptions options = new XmlOptions();
-                    options.setSavePrettyPrint();
-                    xml.save(out, options);
-                } catch (Exception e){
-                    System.err.println("Failed to parse " + entry.getName() + ", dumping raw content");
-                    dump(zip.getInputStream(entry), out);
+            OutputStream out = new FileOutputStream(f);
+            try {
+                if(entry.getName().endsWith(".xml") || entry.getName().endsWith(".vml") || entry.getName().endsWith(".rels")){
+                    try {
+                        XmlObject xml = XmlObject.Factory.parse(zip.getInputStream(entry));
+                        XmlOptions options = new XmlOptions();
+                        options.setSavePrettyPrint();
+                        xml.save(out, options);
+                    } catch (Exception e){
+                        System.err.println("Failed to parse " + entry.getName() + ", dumping raw content");
+                        IOUtils.copy(zip.getInputStream(entry), out);
+                    }
+                } else {
+                    IOUtils.copy(zip.getInputStream(entry), out);
                 }
-            } else {
-                dump(zip.getInputStream(entry), out);
+            } finally {
+            	out.close();
             }
-            out.close();
-
         }
     }
-
-    protected static void dump(InputStream is, OutputStream out) throws IOException{
-        int pos;
-        byte[] chunk = new byte[2048];
-        while((pos = is.read(chunk)) > 0) out.write(chunk, 0, pos);
-
-    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java b/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java
index 7677426..2274418 100644
--- a/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java
+++ b/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java
@@ -96,6 +96,7 @@
    private String formatString;
    private final DataFormatter formatter;
    private int rowNum;
+   private int nextRowNum;      // some sheets do not have rowNums, Excel can read them so we should try to handle them correctly as well
    private String cellRef;
    private boolean formulasNotResults;
 
@@ -240,7 +241,12 @@
           headerFooter.setLength(0);
        }
        else if("row".equals(name)) {
-           rowNum = Integer.parseInt(attributes.getValue("r")) - 1;
+           String rowNumStr = attributes.getValue("r");
+           if(rowNumStr != null) {
+               rowNum = Integer.parseInt(rowNumStr) - 1;
+           } else {
+               rowNum = nextRowNum;
+           }
            output.startRow(rowNum);
        }
        // c => cell
@@ -343,7 +349,7 @@
 
                case NUMBER:
                    String n = value.toString();
-                   if (this.formatString != null)
+                   if (this.formatString != null && n.length() > 0)
                        thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
                    else
                        thisStr = n;
@@ -370,6 +376,9 @@
           
           // Finish up the row
           output.endRow(rowNum);
+          
+          // some sheets do not have rowNum set in the XML, Excel can read them so we should try to read them as well
+          nextRowNum = rowNum + 1;
        } else if ("sheetData".equals(name)) {
            // Handle any "missing" cells which had comments attached
            checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_SHEET_DATA);
diff --git a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java
index 6f43ba1..39ef5be 100644
--- a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java
+++ b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java
@@ -80,7 +80,11 @@
         }
         POIXMLTextExtractor extractor =
                 new XSSFExcelExtractor(args[0]);
-        System.out.println(extractor.getText());
+        try {
+            System.out.println(extractor.getText());
+        } finally {
+            extractor.close();
+        }
     }
 
     /**
@@ -237,7 +241,7 @@
         if (type == Cell.CELL_TYPE_NUMERIC) {
             CellStyle cs = cell.getCellStyle();
 
-            if (cs.getDataFormatString() != null) {
+            if (cs != null && cs.getDataFormatString() != null) {
                 text.append(formatter.formatRawCellContents(
                         cell.getNumericCellValue(), cs.getDataFormat(), cs.getDataFormatString()
                         ));
diff --git a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
index 53d1b76..3937e3e 100644
--- a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
+++ b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
@@ -22,7 +22,7 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedHashMap;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -30,6 +30,7 @@
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.usermodel.BuiltinFormats;
 import org.apache.poi.ss.usermodel.FontFamily;
 import org.apache.poi.ss.usermodel.FontScheme;
@@ -59,91 +60,93 @@
 
 /**
  * Table of styles shared across all sheets in a workbook.
- *
- * @author ugo
  */
 public class StylesTable extends POIXMLDocumentPart {
-	private final Map<Integer, String> numberFormats = new LinkedHashMap<Integer,String>();
-	private final List<XSSFFont> fonts = new ArrayList<XSSFFont>();
-	private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>();
-	private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>();
-	private final List<CTXf> styleXfs = new ArrayList<CTXf>();
-	private final List<CTXf> xfs = new ArrayList<CTXf>();
+    private final Map<Integer, String> numberFormats = new HashMap<Integer,String>();
+    private final boolean[] usedNumberFormats = new boolean[SpreadsheetVersion.EXCEL2007.getMaxCellStyles()];
+    private final List<XSSFFont> fonts = new ArrayList<XSSFFont>();
+    private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>();
+    private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>();
+    private final List<CTXf> styleXfs = new ArrayList<CTXf>();
+    private final List<CTXf> xfs = new ArrayList<CTXf>();
 
-	private final List<CTDxf> dxfs = new ArrayList<CTDxf>();
+    private final List<CTDxf> dxfs = new ArrayList<CTDxf>();
 
-	/**
-	 * The first style id available for use as a custom style
-	 */
-	public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1;
+    /**
+     * The first style id available for use as a custom style
+     */
+    public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1;
+    private static final int MAXIMUM_STYLE_ID = SpreadsheetVersion.EXCEL2007.getMaxCellStyles();
 
-	private StyleSheetDocument doc;
-	private ThemesTable theme;
+    private StyleSheetDocument doc;
+    private ThemesTable theme;
 
-	/**
-	 * Create a new, empty StylesTable
-	 */
-	public StylesTable() {
-		super();
-		doc = StyleSheetDocument.Factory.newInstance();
-		doc.addNewStyleSheet();
-		// Initialization required in order to make the document readable by MSExcel
-		initialize();
-	}
+    /**
+     * Create a new, empty StylesTable
+     */
+    public StylesTable() {
+        super();
+        doc = StyleSheetDocument.Factory.newInstance();
+        doc.addNewStyleSheet();
+        // Initialization required in order to make the document readable by MSExcel
+        initialize();
+    }
 
-	public StylesTable(PackagePart part, PackageRelationship rel) throws IOException {
-		super(part, rel);
-		readFrom(part.getInputStream());
-	}
+    public StylesTable(PackagePart part, PackageRelationship rel) throws IOException {
+        super(part, rel);
+        readFrom(part.getInputStream());
+    }
 
-	public ThemesTable getTheme() {
+    public ThemesTable getTheme() {
         return theme;
     }
 
     public void setTheme(ThemesTable theme) {
         this.theme = theme;
-        
+
         // Pass the themes table along to things which need to 
         //  know about it, but have already been created by now
         for(XSSFFont font : fonts) {
-           font.setThemesTable(theme);
+            font.setThemesTable(theme);
         }
         for(XSSFCellBorder border : borders) {
-           border.setThemesTable(theme);
+            border.setThemesTable(theme);
         }
     }
 
-	/**
-	 * Read this shared styles table from an XML file.
-	 *
-	 * @param is The input stream containing the XML document.
-	 * @throws IOException if an error occurs while reading.
-	 */
+    /**
+     * Read this shared styles table from an XML file.
+     *
+     * @param is The input stream containing the XML document.
+     * @throws IOException if an error occurs while reading.
+     */
     @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
-	protected void readFrom(InputStream is) throws IOException {
-		try {
-			doc = StyleSheetDocument.Factory.parse(is);
+    protected void readFrom(InputStream is) throws IOException {
+        try {
+            doc = StyleSheetDocument.Factory.parse(is);
 
             CTStylesheet styleSheet = doc.getStyleSheet();
 
             // Grab all the different bits we care about
-			CTNumFmts ctfmts = styleSheet.getNumFmts();
+            CTNumFmts ctfmts = styleSheet.getNumFmts();
             if( ctfmts != null){
                 for (CTNumFmt nfmt : ctfmts.getNumFmtArray()) {
-                    numberFormats.put((int)nfmt.getNumFmtId(), nfmt.getFormatCode());
+                    int formatId = (int)nfmt.getNumFmtId();
+                    numberFormats.put(formatId, nfmt.getFormatCode());
+                    usedNumberFormats[formatId] = true;
                 }
             }
 
             CTFonts ctfonts = styleSheet.getFonts();
             if(ctfonts != null){
-				int idx = 0;
-				for (CTFont font : ctfonts.getFontArray()) {
-				   // Create the font and save it. Themes Table supplied later
-					XSSFFont f = new XSSFFont(font, idx);
-					fonts.add(f);
-					idx++;
-				}
-			}
+                int idx = 0;
+                for (CTFont font : ctfonts.getFontArray()) {
+                    // Create the font and save it. Themes Table supplied later
+                    XSSFFont f = new XSSFFont(font, idx);
+                    fonts.add(f);
+                    idx++;
+                }
+            }
             CTFills ctfills = styleSheet.getFills();
             if(ctfills != null){
                 for (CTFill fill : ctfills.getFillArray()) {
@@ -165,401 +168,409 @@
             if(cellStyleXfs != null) styleXfs.addAll(Arrays.asList(cellStyleXfs.getXfArray()));
 
             CTDxfs styleDxfs = styleSheet.getDxfs();
-			if(styleDxfs != null) dxfs.addAll(Arrays.asList(styleDxfs.getDxfArray()));
+            if(styleDxfs != null) dxfs.addAll(Arrays.asList(styleDxfs.getDxfArray()));
 
-		} catch (XmlException e) {
-			throw new IOException(e.getLocalizedMessage());
-		}
-	}
+        } catch (XmlException e) {
+            throw new IOException(e.getLocalizedMessage());
+        }
+    }
 
-	// ===========================================================
-	//  Start of style related getters and setters
-	// ===========================================================
+    // ===========================================================
+    //  Start of style related getters and setters
+    // ===========================================================
 
-	public String getNumberFormatAt(int idx) {
-		return numberFormats.get(idx);
-	}
+    public String getNumberFormatAt(int idx) {
+        return numberFormats.get(idx);
+    }
 
-	public int putNumberFormat(String fmt) {
-		if (numberFormats.containsValue(fmt)) {
-			// Find the key, and return that
-			for(Integer key : numberFormats.keySet() ) {
-				if(numberFormats.get(key).equals(fmt)) {
-					return key;
-				}
-			}
-			throw new IllegalStateException("Found the format, but couldn't figure out where - should never happen!");
-		}
+    public int putNumberFormat(String fmt) {
+        if (numberFormats.containsValue(fmt)) {
+            // Find the key, and return that
+            for (Entry<Integer,String> numFmt : numberFormats.entrySet()) {
+                if(numFmt.getValue().equals(fmt)) {
+                    return numFmt.getKey();
+                }
+            }
+            throw new IllegalStateException("Found the format, but couldn't figure out where - should never happen!");
+        }
 
-		// Find a spare key, and add that
-		int newKey = FIRST_CUSTOM_STYLE_ID;
-		while(numberFormats.containsKey(newKey)) {
-			newKey++;
-		}
-		numberFormats.put(newKey, fmt);
-		return newKey;
-	}
+        // Find a spare key, and add that
+        for (int i=FIRST_CUSTOM_STYLE_ID; i<usedNumberFormats.length; i++) {
+            if (!usedNumberFormats[i]) {
+                usedNumberFormats[i] = true;
+                numberFormats.put(i, fmt);
+                return i;
+            }
+        }
+        throw new IllegalStateException("The maximum number of Data Formats was exceeded. " +
+                "You can define up to " + usedNumberFormats.length + " formats in a .xlsx Workbook");
+    }
 
-	public XSSFFont getFontAt(int idx) {
-		return fonts.get(idx);
-	}
+    public XSSFFont getFontAt(int idx) {
+        return fonts.get(idx);
+    }
 
-	/**
-	 * Records the given font in the font table.
-	 * Will re-use an existing font index if this
-	 *  font matches another, EXCEPT if forced
-	 *  registration is requested.
-	 * This allows people to create several fonts
-	 *  then customise them later.
-	 * Note - End Users probably want to call
-	 *  {@link XSSFFont#registerTo(StylesTable)}
-	 */
-	public int putFont(XSSFFont font, boolean forceRegistration) {
-		int idx = -1;
-		if(!forceRegistration) {
-			idx = fonts.indexOf(font);
-		}
+    /**
+     * Records the given font in the font table.
+     * Will re-use an existing font index if this
+     *  font matches another, EXCEPT if forced
+     *  registration is requested.
+     * This allows people to create several fonts
+     *  then customise them later.
+     * Note - End Users probably want to call
+     *  {@link XSSFFont#registerTo(StylesTable)}
+     */
+    public int putFont(XSSFFont font, boolean forceRegistration) {
+        int idx = -1;
+        if(!forceRegistration) {
+            idx = fonts.indexOf(font);
+        }
 
-		if (idx != -1) {
-			return idx;
-		}
-		
-		idx = fonts.size();
-		fonts.add(font);
-		return idx;
-	}
-	public int putFont(XSSFFont font) {
-		return putFont(font, false);
-	}
+        if (idx != -1) {
+            return idx;
+        }
 
-	public XSSFCellStyle getStyleAt(int idx) {
-		int styleXfId = 0;
+        idx = fonts.size();
+        fonts.add(font);
+        return idx;
+    }
+    public int putFont(XSSFFont font) {
+        return putFont(font, false);
+    }
 
-		// 0 is the empty default
-		if(xfs.get(idx).getXfId() > 0) {
-			styleXfId = (int) xfs.get(idx).getXfId();
-		}
+    public XSSFCellStyle getStyleAt(int idx) {
+        int styleXfId = 0;
 
-		return new XSSFCellStyle(idx, styleXfId, this, theme);
-	}
-	public int putStyle(XSSFCellStyle style) {
-		CTXf mainXF = style.getCoreXf();
+        // 0 is the empty default
+        if(xfs.get(idx).getXfId() > 0) {
+            styleXfId = (int) xfs.get(idx).getXfId();
+        }
 
-		if(! xfs.contains(mainXF)) {
-			xfs.add(mainXF);
-		}
-		return xfs.indexOf(mainXF);
-	}
+        return new XSSFCellStyle(idx, styleXfId, this, theme);
+    }
+    public int putStyle(XSSFCellStyle style) {
+        CTXf mainXF = style.getCoreXf();
 
-	public XSSFCellBorder getBorderAt(int idx) {
-		return borders.get(idx);
-	}
+        if(! xfs.contains(mainXF)) {
+            xfs.add(mainXF);
+        }
+        return xfs.indexOf(mainXF);
+    }
 
-	public int putBorder(XSSFCellBorder border) {
-		int idx = borders.indexOf(border);
-		if (idx != -1) {
-			return idx;
-		}
-		borders.add(border);
-		border.setThemesTable(theme);
-		return borders.size() - 1;
-	}
+    public XSSFCellBorder getBorderAt(int idx) {
+        return borders.get(idx);
+    }
 
-	public XSSFCellFill getFillAt(int idx) {
-		return fills.get(idx);
-	}
+    public int putBorder(XSSFCellBorder border) {
+        int idx = borders.indexOf(border);
+        if (idx != -1) {
+            return idx;
+        }
+        borders.add(border);
+        border.setThemesTable(theme);
+        return borders.size() - 1;
+    }
 
-	public List<XSSFCellBorder> getBorders(){
-		return borders;
-	}
+    public XSSFCellFill getFillAt(int idx) {
+        return fills.get(idx);
+    }
 
-	public List<XSSFCellFill> getFills(){
-		return fills;
-	}
+    public List<XSSFCellBorder> getBorders(){
+        return borders;
+    }
 
-	public List<XSSFFont> getFonts(){
-		return fonts;
-	}
+    public List<XSSFCellFill> getFills(){
+        return fills;
+    }
 
-	public Map<Integer, String> getNumberFormats(){
-		return numberFormats;
-	}
+    public List<XSSFFont> getFonts(){
+        return fonts;
+    }
 
-	public int putFill(XSSFCellFill fill) {
-		int idx = fills.indexOf(fill);
-		if (idx != -1) {
-			return idx;
-		}
-		fills.add(fill);
-		return fills.size() - 1;
-	}
+    public Map<Integer, String> getNumberFormats(){
+        return numberFormats;
+    }
 
-	public CTXf getCellXfAt(int idx) {
-		return xfs.get(idx);
-	}
-	public int putCellXf(CTXf cellXf) {
-		xfs.add(cellXf);
-		return xfs.size();
-	}
-   public void replaceCellXfAt(int idx, CTXf cellXf) {
-      xfs.set(idx, cellXf);
-   }
+    public int putFill(XSSFCellFill fill) {
+        int idx = fills.indexOf(fill);
+        if (idx != -1) {
+            return idx;
+        }
+        fills.add(fill);
+        return fills.size() - 1;
+    }
 
-	public CTXf getCellStyleXfAt(int idx) {
-		return idx < styleXfs.size() ? styleXfs.get(idx) : null;
-	}
-	public int putCellStyleXf(CTXf cellStyleXf) {
-		styleXfs.add(cellStyleXf);
-		return styleXfs.size();
-	}
-	public void replaceCellStyleXfAt(int idx, CTXf cellStyleXf) {
-	   styleXfs.set(idx, cellStyleXf);
-	}
-	
-	/**
-	 * get the size of cell styles
-	 */
-	public int getNumCellStyles(){
+    public CTXf getCellXfAt(int idx) {
+        return xfs.get(idx);
+    }
+    public int putCellXf(CTXf cellXf) {
+        xfs.add(cellXf);
+        return xfs.size();
+    }
+    public void replaceCellXfAt(int idx, CTXf cellXf) {
+        xfs.set(idx, cellXf);
+    }
+
+    public CTXf getCellStyleXfAt(int idx) {
+        return idx < styleXfs.size() ? styleXfs.get(idx) : null;
+    }
+    public int putCellStyleXf(CTXf cellStyleXf) {
+        styleXfs.add(cellStyleXf);
+        return styleXfs.size();
+    }
+    public void replaceCellStyleXfAt(int idx, CTXf cellStyleXf) {
+        styleXfs.set(idx, cellStyleXf);
+    }
+
+    /**
+     * get the size of cell styles
+     */
+    public int getNumCellStyles(){
         // Each cell style has a unique xfs entry
         // Several might share the same styleXfs entry
         return xfs.size();
-	}
+    }
 
-	/**
-	 * For unit testing only
-	 */
-	public int _getNumberFormatSize() {
-		return numberFormats.size();
-	}
+    /**
+     * For unit testing only
+     */
+    public int _getNumberFormatSize() {
+        return numberFormats.size();
+    }
 
-	/**
-	 * For unit testing only
-	 */
-	public int _getXfsSize() {
-		return xfs.size();
-	}
-	/**
-	 * For unit testing only
-	 */
-	public int _getStyleXfsSize() {
-		return styleXfs.size();
-	}
-	/**
-	 * For unit testing only!
-	 */
-	public CTStylesheet getCTStylesheet() {
-		return doc.getStyleSheet();
-	}
+    /**
+     * For unit testing only
+     */
+    public int _getXfsSize() {
+        return xfs.size();
+    }
+    /**
+     * For unit testing only
+     */
+    public int _getStyleXfsSize() {
+        return styleXfs.size();
+    }
+    /**
+     * For unit testing only!
+     */
+    public CTStylesheet getCTStylesheet() {
+        return doc.getStyleSheet();
+    }
     public int _getDXfsSize() {
         return dxfs.size();
     }
 
 
-	/**
-	 * Write this table out as XML.
-	 *
-	 * @param out The stream to write to.
-	 * @throws IOException if an error occurs while writing.
-	 */
-	public void writeTo(OutputStream out) throws IOException {
-		XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS);
+    /**
+     * Write this table out as XML.
+     *
+     * @param out The stream to write to.
+     * @throws IOException if an error occurs while writing.
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS);
 
-		// Work on the current one
-		// Need to do this, as we don't handle
-		//  all the possible entries yet
-		CTStylesheet styleSheet = doc.getStyleSheet();
+        // Work on the current one
+        // Need to do this, as we don't handle
+        //  all the possible entries yet
+        CTStylesheet styleSheet = doc.getStyleSheet();
 
-		// Formats
-		CTNumFmts formats = CTNumFmts.Factory.newInstance();
-		formats.setCount(numberFormats.size());
-		for (Entry<Integer, String> fmt : numberFormats.entrySet()) {
-			CTNumFmt ctFmt = formats.addNewNumFmt();
-			ctFmt.setNumFmtId(fmt.getKey());
-			ctFmt.setFormatCode(fmt.getValue());
-		}
-		styleSheet.setNumFmts(formats);
+        // Formats
+        CTNumFmts formats = CTNumFmts.Factory.newInstance();
+        formats.setCount(numberFormats.size());
+        for (int fmtId=0; fmtId<usedNumberFormats.length; fmtId++) {
+            if (usedNumberFormats[fmtId]) {
+                CTNumFmt ctFmt = formats.addNewNumFmt();
+                ctFmt.setNumFmtId(fmtId);
+                ctFmt.setFormatCode(numberFormats.get(fmtId));
+            }
+        }
+        styleSheet.setNumFmts(formats);
 
-		int idx;
-		// Fonts
-		CTFonts ctFonts = styleSheet.getFonts();
-		if (ctFonts == null) {
-			ctFonts = CTFonts.Factory.newInstance();
-		}
-		ctFonts.setCount(fonts.size());
-		CTFont[] ctfnt = new CTFont[fonts.size()];
-		idx = 0;
-		for(XSSFFont f : fonts) ctfnt[idx++] = f.getCTFont();
-		ctFonts.setFontArray(ctfnt);
-		styleSheet.setFonts(ctFonts);
+        int idx;
+        // Fonts
+        CTFonts ctFonts = styleSheet.getFonts();
+        if (ctFonts == null) {
+            ctFonts = CTFonts.Factory.newInstance();
+        }
+        ctFonts.setCount(fonts.size());
+        CTFont[] ctfnt = new CTFont[fonts.size()];
+        idx = 0;
+        for(XSSFFont f : fonts) ctfnt[idx++] = f.getCTFont();
+        ctFonts.setFontArray(ctfnt);
+        styleSheet.setFonts(ctFonts);
 
-		// Fills
-		CTFills ctFills = styleSheet.getFills();
-		if (ctFills == null) {
-			ctFills = CTFills.Factory.newInstance();
-		}
-		ctFills.setCount(fills.size());
-		CTFill[] ctf = new CTFill[fills.size()];
-		idx = 0;
-		for(XSSFCellFill f : fills) ctf[idx++] = f.getCTFill();
-		ctFills.setFillArray(ctf);
-		styleSheet.setFills(ctFills);
+        // Fills
+        CTFills ctFills = styleSheet.getFills();
+        if (ctFills == null) {
+            ctFills = CTFills.Factory.newInstance();
+        }
+        ctFills.setCount(fills.size());
+        CTFill[] ctf = new CTFill[fills.size()];
+        idx = 0;
+        for(XSSFCellFill f : fills) ctf[idx++] = f.getCTFill();
+        ctFills.setFillArray(ctf);
+        styleSheet.setFills(ctFills);
 
-		// Borders
-		CTBorders ctBorders = styleSheet.getBorders();
-		if (ctBorders == null) {
-			ctBorders = CTBorders.Factory.newInstance();
-		}
-		ctBorders.setCount(borders.size());
-		CTBorder[] ctb = new CTBorder[borders.size()];
-		idx = 0;
-		for(XSSFCellBorder b : borders) ctb[idx++] = b.getCTBorder();
-		ctBorders.setBorderArray(ctb);
-		styleSheet.setBorders(ctBorders);
+        // Borders
+        CTBorders ctBorders = styleSheet.getBorders();
+        if (ctBorders == null) {
+            ctBorders = CTBorders.Factory.newInstance();
+        }
+        ctBorders.setCount(borders.size());
+        CTBorder[] ctb = new CTBorder[borders.size()];
+        idx = 0;
+        for(XSSFCellBorder b : borders) ctb[idx++] = b.getCTBorder();
+        ctBorders.setBorderArray(ctb);
+        styleSheet.setBorders(ctBorders);
 
-		// Xfs
-		if(xfs.size() > 0) {
-			CTCellXfs ctXfs = styleSheet.getCellXfs();
-			if (ctXfs == null) {
-				ctXfs = CTCellXfs.Factory.newInstance();
-			}
-			ctXfs.setCount(xfs.size());
-			ctXfs.setXfArray(
-					xfs.toArray(new CTXf[xfs.size()])
-			);
-			styleSheet.setCellXfs(ctXfs);
-		}
+        // Xfs
+        if(xfs.size() > 0) {
+            CTCellXfs ctXfs = styleSheet.getCellXfs();
+            if (ctXfs == null) {
+                ctXfs = CTCellXfs.Factory.newInstance();
+            }
+            ctXfs.setCount(xfs.size());
+            ctXfs.setXfArray(
+                    xfs.toArray(new CTXf[xfs.size()])
+            );
+            styleSheet.setCellXfs(ctXfs);
+        }
 
-		// Style xfs
-		if(styleXfs.size() > 0) {
-			CTCellStyleXfs ctSXfs = styleSheet.getCellStyleXfs();
-			if (ctSXfs == null) {
-				ctSXfs = CTCellStyleXfs.Factory.newInstance();
-			}
-			ctSXfs.setCount(styleXfs.size());
-			ctSXfs.setXfArray(
-					styleXfs.toArray(new CTXf[styleXfs.size()])
-			);
-			styleSheet.setCellStyleXfs(ctSXfs);
-		}
+        // Style xfs
+        if(styleXfs.size() > 0) {
+            CTCellStyleXfs ctSXfs = styleSheet.getCellStyleXfs();
+            if (ctSXfs == null) {
+                ctSXfs = CTCellStyleXfs.Factory.newInstance();
+            }
+            ctSXfs.setCount(styleXfs.size());
+            ctSXfs.setXfArray(
+                    styleXfs.toArray(new CTXf[styleXfs.size()])
+            );
+            styleSheet.setCellStyleXfs(ctSXfs);
+        }
 
-		// Style dxfs
-		if(dxfs.size() > 0) {
-			CTDxfs ctDxfs = styleSheet.getDxfs();
-			if (ctDxfs == null) {
-				ctDxfs = CTDxfs.Factory.newInstance();
-			}
-			ctDxfs.setCount(dxfs.size());
-			ctDxfs.setDxfArray(dxfs.toArray(new CTDxf[dxfs.size()])
-			);
-			styleSheet.setDxfs(ctDxfs);
-		}
+        // Style dxfs
+        if(dxfs.size() > 0) {
+            CTDxfs ctDxfs = styleSheet.getDxfs();
+            if (ctDxfs == null) {
+                ctDxfs = CTDxfs.Factory.newInstance();
+            }
+            ctDxfs.setCount(dxfs.size());
+            ctDxfs.setDxfArray(dxfs.toArray(new CTDxf[dxfs.size()]));
+            styleSheet.setDxfs(ctDxfs);
+        }
 
-		// Save
-		doc.save(out, options);
-	}
+        // Save
+        doc.save(out, options);
+    }
 
-	@Override
-	protected void commit() throws IOException {
-		PackagePart part = getPackagePart();
-		OutputStream out = part.getOutputStream();
-		writeTo(out);
-		out.close();
-	}
+    @Override
+    protected void commit() throws IOException {
+        PackagePart part = getPackagePart();
+        OutputStream out = part.getOutputStream();
+        writeTo(out);
+        out.close();
+    }
 
-	private void initialize() {
-		//CTFont ctFont = createDefaultFont();
-		XSSFFont xssfFont = createDefaultFont();
-		fonts.add(xssfFont);
+    private void initialize() {
+        //CTFont ctFont = createDefaultFont();
+        XSSFFont xssfFont = createDefaultFont();
+        fonts.add(xssfFont);
 
-		CTFill[] ctFill = createDefaultFills();
-		fills.add(new XSSFCellFill(ctFill[0]));
-		fills.add(new XSSFCellFill(ctFill[1]));
+        CTFill[] ctFill = createDefaultFills();
+        fills.add(new XSSFCellFill(ctFill[0]));
+        fills.add(new XSSFCellFill(ctFill[1]));
 
-		CTBorder ctBorder = createDefaultBorder();
-		borders.add(new XSSFCellBorder(ctBorder));
+        CTBorder ctBorder = createDefaultBorder();
+        borders.add(new XSSFCellBorder(ctBorder));
 
-		CTXf styleXf = createDefaultXf();
-		styleXfs.add(styleXf);
-		CTXf xf = createDefaultXf();
-		xf.setXfId(0);
-		xfs.add(xf);
-	}
+        CTXf styleXf = createDefaultXf();
+        styleXfs.add(styleXf);
+        CTXf xf = createDefaultXf();
+        xf.setXfId(0);
+        xfs.add(xf);
+    }
 
-	private static CTXf createDefaultXf() {
-		CTXf ctXf = CTXf.Factory.newInstance();
-		ctXf.setNumFmtId(0);
-		ctXf.setFontId(0);
-		ctXf.setFillId(0);
-		ctXf.setBorderId(0);
-		return ctXf;
-	}
-	private static CTBorder createDefaultBorder() {
-		CTBorder ctBorder = CTBorder.Factory.newInstance();
-		ctBorder.addNewBottom();
-		ctBorder.addNewTop();
-		ctBorder.addNewLeft();
-		ctBorder.addNewRight();
-		ctBorder.addNewDiagonal();
-		return ctBorder;
-	}
+    private static CTXf createDefaultXf() {
+        CTXf ctXf = CTXf.Factory.newInstance();
+        ctXf.setNumFmtId(0);
+        ctXf.setFontId(0);
+        ctXf.setFillId(0);
+        ctXf.setBorderId(0);
+        return ctXf;
+    }
+    private static CTBorder createDefaultBorder() {
+        CTBorder ctBorder = CTBorder.Factory.newInstance();
+        ctBorder.addNewBottom();
+        ctBorder.addNewTop();
+        ctBorder.addNewLeft();
+        ctBorder.addNewRight();
+        ctBorder.addNewDiagonal();
+        return ctBorder;
+    }
 
 
-	private static CTFill[] createDefaultFills() {
-		CTFill[] ctFill = new CTFill[]{CTFill.Factory.newInstance(),CTFill.Factory.newInstance()};
-		ctFill[0].addNewPatternFill().setPatternType(STPatternType.NONE);
-		ctFill[1].addNewPatternFill().setPatternType(STPatternType.DARK_GRAY);
-		return ctFill;
-	}
+    private static CTFill[] createDefaultFills() {
+        CTFill[] ctFill = new CTFill[]{CTFill.Factory.newInstance(),CTFill.Factory.newInstance()};
+        ctFill[0].addNewPatternFill().setPatternType(STPatternType.NONE);
+        ctFill[1].addNewPatternFill().setPatternType(STPatternType.DARK_GRAY);
+        return ctFill;
+    }
 
-	private static XSSFFont createDefaultFont() {
-		CTFont ctFont = CTFont.Factory.newInstance();
-		XSSFFont xssfFont=new XSSFFont(ctFont, 0);
-		xssfFont.setFontHeightInPoints(XSSFFont.DEFAULT_FONT_SIZE);
-		xssfFont.setColor(XSSFFont.DEFAULT_FONT_COLOR);//setTheme
-		xssfFont.setFontName(XSSFFont.DEFAULT_FONT_NAME);
-		xssfFont.setFamily(FontFamily.SWISS);
-		xssfFont.setScheme(FontScheme.MINOR);
-		return xssfFont;
-	}
+    private static XSSFFont createDefaultFont() {
+        CTFont ctFont = CTFont.Factory.newInstance();
+        XSSFFont xssfFont=new XSSFFont(ctFont, 0);
+        xssfFont.setFontHeightInPoints(XSSFFont.DEFAULT_FONT_SIZE);
+        xssfFont.setColor(XSSFFont.DEFAULT_FONT_COLOR);//setTheme
+        xssfFont.setFontName(XSSFFont.DEFAULT_FONT_NAME);
+        xssfFont.setFamily(FontFamily.SWISS);
+        xssfFont.setScheme(FontScheme.MINOR);
+        return xssfFont;
+    }
 
-	public CTDxf getDxfAt(int idx) {
-		return dxfs.get(idx);
-	}
+    public CTDxf getDxfAt(int idx) {
+        return dxfs.get(idx);
+    }
 
-	public int putDxf(CTDxf dxf) {
-		this.dxfs.add(dxf);
-		return this.dxfs.size();
-	}
+    public int putDxf(CTDxf dxf) {
+        this.dxfs.add(dxf);
+        return this.dxfs.size();
+    }
 
-	public XSSFCellStyle createCellStyle() {
-		CTXf xf = CTXf.Factory.newInstance();
-		xf.setNumFmtId(0);
-		xf.setFontId(0);
-		xf.setFillId(0);
-		xf.setBorderId(0);
-		xf.setXfId(0);
-		int xfSize = styleXfs.size();
-		int indexXf = putCellXf(xf);
-		return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme);
-	}
+    public XSSFCellStyle createCellStyle() {
+        int xfSize = styleXfs.size();
+        if (xfSize > MAXIMUM_STYLE_ID)
+            throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " +
+                      "You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook");
 
-	/**
-	 * Finds a font that matches the one with the supplied attributes
-	 */
-	public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) {
-		for (XSSFFont font : fonts) {
-			if (	(font.getBoldweight() == boldWeight)
-					&& font.getColor() == color
-					&& font.getFontHeight() == fontHeight
-					&& font.getFontName().equals(name)
-					&& font.getItalic() == italic
-					&& font.getStrikeout() == strikeout
-					&& font.getTypeOffset() == typeOffset
-					&& font.getUnderline() == underline)
-			{
-				return font;
-			}
-		}
-		return null;
-	}
+        CTXf xf = CTXf.Factory.newInstance();
+        xf.setNumFmtId(0);
+        xf.setFontId(0);
+        xf.setFillId(0);
+        xf.setBorderId(0);
+        xf.setXfId(0);
+        int indexXf = putCellXf(xf);
+        return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme);
+    }
+
+    /**
+     * Finds a font that matches the one with the supplied attributes
+     */
+    public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) {
+        for (XSSFFont font : fonts) {
+            if (	(font.getBoldweight() == boldWeight)
+                    && font.getColor() == color
+                    && font.getFontHeight() == fontHeight
+                    && font.getFontName().equals(name)
+                    && font.getItalic() == italic
+                    && font.getStrikeout() == strikeout
+                    && font.getTypeOffset() == typeOffset
+                    && font.getUnderline() == underline)
+            {
+                return font;
+            }
+        }
+        return null;
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java
index 0e8f906..bf58989 100644
--- a/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java
+++ b/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java
@@ -45,7 +45,7 @@
         try {
            theme = ThemeDocument.Factory.parse(part.getInputStream());
         } catch(XmlException e) {
-           throw new IOException(e.getLocalizedMessage());
+           throw new IOException(e.getLocalizedMessage(), e);
         }
     }
 
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
index f590cc0..b0d3580 100644
--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
@@ -22,6 +22,7 @@
 import java.util.Calendar;
 import java.util.Date;
 
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.FormulaParseException;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.usermodel.Cell;
@@ -227,6 +228,11 @@
     public void setCellValue(RichTextString value)
     {
         ensureRichTextStringType();
+
+        if(value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){
+            throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
+        }
+
         ((RichTextValue)_value).setValue(value);
     }
 
@@ -241,6 +247,11 @@
     public void setCellValue(String value)
     {
         ensureTypeOrFormulaType(CELL_TYPE_STRING);
+        
+        if(value != null && value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){
+            throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
+        }
+
         if(_value.getType()==CELL_TYPE_FORMULA)
             ((StringFormulaValue)_value).setPreEvaluatedValue(value);
         else
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
index ae6c4c4..cefc4f3 100644
--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
@@ -431,7 +431,9 @@
     }
 
     /**
-     * Returns the merged region at the specified index
+     * Returns the merged region at the specified index. If you want multiple
+     * regions, it is faster to call {@link #getMergedRegions()} than to call
+     * this each time.
      *
      * @return the merged region at the specified index
      */
@@ -441,6 +443,17 @@
     }
 
     /**
+     * Returns the list of merged regions. If you want multiple regions, this is
+     * faster than calling {@link #getMergedRegion(int)} each time.
+     *
+     * @return the list of merged regions
+     */
+    @Override
+    public List<CellRangeAddress> getMergedRegions() {
+        return _sh.getMergedRegions();
+    }
+
+    /**
      *  Returns an iterator of the physical rows
      *
      * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
index 87d8847..bd75179 100644
--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
@@ -32,6 +32,7 @@
 import java.util.zip.ZipOutputStream;
 
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.internal.ZipHelper;
 import org.apache.poi.ss.formula.udf.UDFFinder;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.CreationHelper;
@@ -334,7 +335,7 @@
     }
     private void injectData(File zipfile, OutputStream out) throws IOException 
     {
-        ZipFile zip = new ZipFile(zipfile);
+        ZipFile zip = ZipHelper.openZipFile(zipfile);
         try
         {
             ZipOutputStream zos = new ZipOutputStream(out);
@@ -709,9 +710,16 @@
     @Override
     public void removeSheetAt(int index)
     {
-        XSSFSheet xSheet=_wb.getSheetAt(index);
+        // Get the sheet to be removed
+        XSSFSheet xSheet = _wb.getSheetAt(index);
+        SXSSFSheet sxSheet = getSXSSFSheet(xSheet);
+        
+        // De-register it
         _wb.removeSheetAt(index);
         deregisterSheetMapping(xSheet);
+        
+        // Clean up temporary resources
+        sxSheet.dispose();
     }
 
     /**
@@ -831,7 +839,7 @@
 
     /**
      * Closes the underlying {@link XSSFWorkbook} and {@link OPCPackage} 
-     *  on which this Workbook is based, if any. Has no effect on Worbooks
+     *  on which this Workbook is based, if any. Has no effect on Workbooks
      *  created from scratch.
      */
     @Override
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java
index d91f5ca..e307a4a 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java
@@ -17,149 +17,230 @@
 package org.apache.poi.xssf.usermodel;

 

 import org.apache.poi.ss.usermodel.BorderFormatting;

+import org.apache.poi.ss.usermodel.Color;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;

 

 /**

- * @author Yegor Kozlov

+ * XSSF high level representation for Border Formatting component

+ * of Conditional Formatting settings

  */

 public class XSSFBorderFormatting implements BorderFormatting  {

     CTBorder _border;

 

-    /*package*/ XSSFBorderFormatting(CTBorder border){

+    /*package*/ XSSFBorderFormatting(CTBorder border) {

         _border = border;

     }

 

-    public short getBorderBottom(){

+    public short getBorderBottom() {

         STBorderStyle.Enum ptrn = _border.isSetBottom() ? _border.getBottom().getStyle() : null;

         return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);

     }

 

-    public short getBorderDiagonal(){

+    public short getBorderDiagonal() {

         STBorderStyle.Enum ptrn = _border.isSetDiagonal() ? _border.getDiagonal().getStyle() : null;

         return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);

     }

 

-    public short getBorderLeft(){

+    public short getBorderLeft() {

         STBorderStyle.Enum ptrn = _border.isSetLeft() ? _border.getLeft().getStyle() : null;

         return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);

     }

 

-    public short getBorderRight(){

+    public short getBorderRight() {

         STBorderStyle.Enum ptrn = _border.isSetRight() ? _border.getRight().getStyle() : null;

         return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);

     }

 

-    public short getBorderTop(){

+    public short getBorderTop() {

         STBorderStyle.Enum ptrn = _border.isSetTop() ? _border.getTop().getStyle() : null;

         return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);

     }

 

-    public short getBottomBorderColor(){

-        if(!_border.isSetBottom()) return 0;

+    public XSSFColor getBottomBorderColorColor() {

+        if(!_border.isSetBottom()) return null;

 

         CTBorderPr pr = _border.getBottom();

-        return (short)pr.getColor().getIndexed();

+        return new XSSFColor(pr.getColor());

+    }

+    public short getBottomBorderColor() {

+        XSSFColor color = getBottomBorderColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public short getDiagonalBorderColor(){

-        if(!_border.isSetDiagonal()) return 0;

+    public XSSFColor getDiagonalBorderColorColor() {

+        if(!_border.isSetDiagonal()) return null;

 

         CTBorderPr pr = _border.getDiagonal();

-        return (short)pr.getColor().getIndexed();

+        return new XSSFColor(pr.getColor());

+    }

+    public short getDiagonalBorderColor() {

+        XSSFColor color = getDiagonalBorderColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public short getLeftBorderColor(){

-        if(!_border.isSetLeft()) return 0;

+    public XSSFColor getLeftBorderColorColor() {

+        if(!_border.isSetLeft()) return null;

 

         CTBorderPr pr = _border.getLeft();

-        return (short)pr.getColor().getIndexed();

+        return new XSSFColor(pr.getColor());

+    }

+    public short getLeftBorderColor() {

+        XSSFColor color = getLeftBorderColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public short getRightBorderColor(){

-        if(!_border.isSetRight()) return 0;

+    public XSSFColor getRightBorderColorColor() {

+        if(!_border.isSetRight()) return null;

 

         CTBorderPr pr = _border.getRight();

-        return (short)pr.getColor().getIndexed();

+        return new XSSFColor(pr.getColor());

+    }

+    public short getRightBorderColor() {

+        XSSFColor color = getRightBorderColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public short getTopBorderColor(){

-        if(!_border.isSetTop()) return 0;

+    public XSSFColor getTopBorderColorColor() {

+        if(!_border.isSetTop()) return null;

 

         CTBorderPr pr = _border.getTop();

-        return (short)pr.getColor().getIndexed();

+        return new XSSFColor(pr.getColor());

+    }

+    public short getTopBorderColor() {

+        XSSFColor color = getRightBorderColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public void setBorderBottom(short border){

+    public void setBorderBottom(short border) {

         CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom();

         if(border == BORDER_NONE) _border.unsetBottom();

         else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));

     }

 

-    public void setBorderDiagonal(short border){

+    public void setBorderDiagonal(short border) {

         CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal();

         if(border == BORDER_NONE) _border.unsetDiagonal();

         else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));

     }

 

-    public void setBorderLeft(short border){

+    public void setBorderLeft(short border) {

         CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft();

         if(border == BORDER_NONE) _border.unsetLeft();

         else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));

     }

 

-    public void setBorderRight(short border){

+    public void setBorderRight(short border) {

         CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight();

         if(border == BORDER_NONE) _border.unsetRight();

         else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));

     }

 

-    public void setBorderTop(short border){

+    public void setBorderTop(short border) {

         CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop();

         if(border == BORDER_NONE) _border.unsetTop();

         else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));

     }

 

-    public void setBottomBorderColor(short color){

+    public void setBottomBorderColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) setBottomBorderColor((CTColor)null);

+        else setBottomBorderColor(xcolor.getCTColor());

+    }

+    public void setBottomBorderColor(short color) {

+        CTColor ctColor = CTColor.Factory.newInstance();

+        ctColor.setIndexed(color);

+        setBottomBorderColor(ctColor);

+    }

+    public void setBottomBorderColor(CTColor color) {

         CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom();

-

-        CTColor ctColor = CTColor.Factory.newInstance();

-        ctColor.setIndexed(color);

-        pr.setColor(ctColor);

+        if (color == null) {

+            pr.unsetColor();

+        } else {

+            pr.setColor(color);

+        }

     }

 

-    public void setDiagonalBorderColor(short color){

+    public void setDiagonalBorderColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) setDiagonalBorderColor((CTColor)null);

+        else setDiagonalBorderColor(xcolor.getCTColor());

+    }

+    public void setDiagonalBorderColor(short color) {

+        CTColor ctColor = CTColor.Factory.newInstance();

+        ctColor.setIndexed(color);

+        setDiagonalBorderColor(ctColor);

+    }

+    public void setDiagonalBorderColor(CTColor color) {

         CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal();

-

-        CTColor ctColor = CTColor.Factory.newInstance();

-        ctColor.setIndexed(color);

-        pr.setColor(ctColor);

+        if (color == null) {

+            pr.unsetColor();

+        } else {

+            pr.setColor(color);

+        }

     }

 

-    public void setLeftBorderColor(short color){

+    public void setLeftBorderColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) setLeftBorderColor((CTColor)null);

+        else setLeftBorderColor(xcolor.getCTColor());

+    }

+    public void setLeftBorderColor(short color) {

+        CTColor ctColor = CTColor.Factory.newInstance();

+        ctColor.setIndexed(color);

+        setLeftBorderColor(ctColor);

+    }

+    public void setLeftBorderColor(CTColor color) {

         CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft();

-

-        CTColor ctColor = CTColor.Factory.newInstance();

-        ctColor.setIndexed(color);

-        pr.setColor(ctColor);

+        if (color == null) {

+            pr.unsetColor();

+        } else {

+            pr.setColor(color);

+        }

     }

 

-    public void setRightBorderColor(short color){

+    public void setRightBorderColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) setRightBorderColor((CTColor)null);

+        else setRightBorderColor(xcolor.getCTColor());

+    }

+    public void setRightBorderColor(short color) {

+        CTColor ctColor = CTColor.Factory.newInstance();

+        ctColor.setIndexed(color);

+        setRightBorderColor(ctColor);

+    }

+    public void setRightBorderColor(CTColor color) {

         CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight();

-

-        CTColor ctColor = CTColor.Factory.newInstance();

-        ctColor.setIndexed(color);

-        pr.setColor(ctColor);

+        if (color == null) {

+            pr.unsetColor();

+        } else {

+            pr.setColor(color);

+        }

     }

 

-    public void setTopBorderColor(short color){

+    public void setTopBorderColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) setTopBorderColor((CTColor)null);

+        else setTopBorderColor(xcolor.getCTColor());

+    }

+    public void setTopBorderColor(short color) {

+        CTColor ctColor = CTColor.Factory.newInstance();

+        ctColor.setIndexed(color);

+        setTopBorderColor(ctColor);

+    }

+    public void setTopBorderColor(CTColor color) {

         CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop();

-

-        CTColor ctColor = CTColor.Factory.newInstance();

-        ctColor.setIndexed(color);

-        pr.setColor(ctColor);

+        if (color == null) {

+            pr.unsetColor();

+        } else {

+            pr.setColor(color);

+        }

     }

-    

 }

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
index df8cbf2..5c16f05 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
@@ -346,6 +346,11 @@
             setCellType(Cell.CELL_TYPE_BLANK);
             return;
         }
+
+        if(str.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){
+            throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
+        }
+
         int cellType = getCellType();
         switch(cellType){
             case Cell.CELL_TYPE_FORMULA:
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
index d1f0759..f83facd 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
@@ -154,6 +154,13 @@
                   _cellXf = CTXf.Factory.parse(
                         src.getCoreXf().toString()
                   );
+                  
+                  // bug 56295: ensure that the fills is available and set correctly
+                  CTFill fill = CTFill.Factory.parse(
+                		  src.getCTFill().toString()
+                		  );
+                  addFill(fill);
+                  
                   // Swap it over
                   _stylesSource.replaceCellXfAt(_cellXfId, _cellXf);
                } catch(XmlException e) {
@@ -187,6 +194,13 @@
         }
     }
 
+	private void addFill(CTFill fill) {
+		int idx = _stylesSource.putFill(new XSSFCellFill(fill));
+
+		_cellXf.setFillId(idx);
+		_cellXf.setApplyFill(true);
+	}
+
     /**
      * Get the type of horizontal alignment for the cell
      *
@@ -444,7 +458,8 @@
      * @return XSSFColor - fill color or <code>null</code> if not set
      */
     public XSSFColor getFillBackgroundXSSFColor() {
-        if(!_cellXf.getApplyFill()) return null;
+    	// bug 56295: handle missing applyFill attribute as "true" because Excel does as well
+        if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return null;
 
         int fillIndex = (int)_cellXf.getFillId();
         XSSFCellFill fg = _stylesSource.getFillAt(fillIndex);
@@ -480,7 +495,8 @@
      * @return XSSFColor - fill color or <code>null</code> if not set
      */
     public XSSFColor getFillForegroundXSSFColor() {
-        if(!_cellXf.getApplyFill()) return null;
+    	// bug 56295: handle missing applyFill attribute as "true" because Excel does as well
+        if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return null;
 
         int fillIndex = (int)_cellXf.getFillId();
         XSSFCellFill fg = _stylesSource.getFillAt(fillIndex);
@@ -515,7 +531,8 @@
      * @see org.apache.poi.ss.usermodel.CellStyle#DIAMONDS
      */
     public short getFillPattern() {
-        if(!_cellXf.getApplyFill()) return 0;
+    	// bug 56295: handle missing applyFill attribute as "true" because Excel does as well
+        if(_cellXf.isSetApplyFill() && !_cellXf.getApplyFill()) return 0;
 
         int fillIndex = (int)_cellXf.getFillId();
         XSSFCellFill fill = _stylesSource.getFillAt(fillIndex);
@@ -586,6 +603,9 @@
     public short getIndex() {
         return (short)this._cellXfId;
     }
+    protected int getUIndex() {
+        return this._cellXfId;
+    }
 
     /**
      * Get the color to use for the left border
@@ -957,6 +977,15 @@
      * @param fmt the index of a data format
      */
     public void setDataFormat(short fmt) {
+        // XSSF supports >32,767 formats
+        setDataFormat(fmt&0xffff);
+    }
+    /**
+     * Set the index of a data format
+     *
+     * @param fmt the index of a data format
+     */
+    public void setDataFormat(int fmt) {
         _cellXf.setApplyNumberFormat(true);
         _cellXf.setNumFmtId(fmt);
     }
@@ -996,10 +1025,7 @@
             ptrn.setBgColor(color.getCTColor());
         }
 
-        int idx = _stylesSource.putFill(new XSSFCellFill(ct));
-
-        _cellXf.setFillId(idx);
-        _cellXf.setApplyFill(true);
+        addFill(ct);
     }
 
     /**
@@ -1052,10 +1078,7 @@
             ptrn.setFgColor(color.getCTColor());
         }
 
-        int idx = _stylesSource.putFill(new XSSFCellFill(ct));
-
-        _cellXf.setFillId(idx);
-        _cellXf.setApplyFill(true);
+        addFill(ct);
     }
 
     /**
@@ -1076,7 +1099,8 @@
      */
     private CTFill getCTFill(){
         CTFill ct;
-        if(_cellXf.getApplyFill()) {
+    	// bug 56295: handle missing applyFill attribute as "true" because Excel does as well
+        if(!_cellXf.isSetApplyFill() || _cellXf.getApplyFill()) {
             int fillIndex = (int)_cellXf.getFillId();
             XSSFCellFill cf = _stylesSource.getFillAt(fillIndex);
 
@@ -1135,10 +1159,7 @@
         if(fp == NO_FILL && ptrn.isSetPatternType()) ptrn.unsetPatternType();
         else ptrn.setPatternType(STPatternType.Enum.forInt(fp + 1));
 
-        int idx = _stylesSource.putFill(new XSSFCellFill(ct));
-
-        _cellXf.setFillId(idx);
-        _cellXf.setApplyFill(true);
+        addFill(ct);
     }
 
     /**
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
index 3082e53..19fd5a5 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
@@ -170,10 +170,7 @@
           return null;
        }
        for(byte c : rgb) {
-          int i = (int)c;
-          if(i < 0) {
-             i += 256;
-          }
+          int i = c & 0xff;
           String cs = Integer.toHexString(i);
           if(cs.length() == 1) {
              sb.append('0');
@@ -316,6 +313,13 @@
         return ctColor;
     }
 
+    public static XSSFColor toXSSFColor(Color color) {
+        if (color != null && !(color instanceof XSSFColor)) {
+            throw new IllegalArgumentException("Only XSSFColor objects are supported");
+        }
+        return (XSSFColor)color;
+    }
+    
     public int hashCode(){
         return ctColor.toString().hashCode();
     }
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java
index 5fdd3aa..51ef179 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java
@@ -145,9 +145,17 @@
 		_comment.setRef(newRef);
       _comments.referenceUpdated(oldRef, _comment);
       
-        if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row)));
+        if(_vmlShape != null) {
+        	_vmlShape.getClientDataArray(0).setRowArray(0, 
+        			new BigInteger(String.valueOf(row)));
+        	
+            // There is a very odd xmlbeans bug when changing the row
+            //  arrays which can lead to corrupt pointer
+            // This call seems to fix them again... See bug #50795
+            _vmlShape.getClientDataList().toString();
+        }
     }
-	
+    
     /**
      * @return the rich text string of the comment
      */
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java
index 127c037..53eb41b 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java
@@ -98,4 +98,8 @@
      public int getNumberOfRules(){

          return _cf.sizeOfCfRuleArray();

      }

+     

+     public String toString() {

+         return _cf.toString();

+     }

 }

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
index 64e49f9..814e73c 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
@@ -19,23 +19,48 @@
 

 package org.apache.poi.xssf.usermodel;

 

+import java.util.HashMap;

+import java.util.Map;

+

 import org.apache.poi.ss.usermodel.*;

+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;

 import org.apache.poi.xssf.usermodel.XSSFFontFormatting;

 import org.apache.poi.xssf.model.StylesTable;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;

-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

 

 /**

- * @author Yegor Kozlov

+ * XSSF suport for Conditional Formatting rules

  */

 public class XSSFConditionalFormattingRule implements ConditionalFormattingRule {

     private final CTCfRule _cfRule;

     private XSSFSheet _sh;

+    

+    private static Map<STCfType.Enum, ConditionType> typeLookup = new HashMap<STCfType.Enum, ConditionType>();

+    static {

+        typeLookup.put(STCfType.CELL_IS, ConditionType.CELL_VALUE_IS);

+        typeLookup.put(STCfType.EXPRESSION, ConditionType.FORMULA);

+        typeLookup.put(STCfType.COLOR_SCALE, ConditionType.COLOR_SCALE);

+        typeLookup.put(STCfType.DATA_BAR, ConditionType.DATA_BAR);

+        typeLookup.put(STCfType.ICON_SET, ConditionType.ICON_SET);

+        

+        // These are all subtypes of Filter, we think...

+        typeLookup.put(STCfType.TOP_10, ConditionType.FILTER);

+        typeLookup.put(STCfType.UNIQUE_VALUES, ConditionType.FILTER);

+        typeLookup.put(STCfType.DUPLICATE_VALUES, ConditionType.FILTER);

+        typeLookup.put(STCfType.CONTAINS_TEXT, ConditionType.FILTER);

+        typeLookup.put(STCfType.NOT_CONTAINS_TEXT, ConditionType.FILTER);

+        typeLookup.put(STCfType.BEGINS_WITH, ConditionType.FILTER);

+        typeLookup.put(STCfType.ENDS_WITH, ConditionType.FILTER);

+        typeLookup.put(STCfType.CONTAINS_BLANKS, ConditionType.FILTER);

+        typeLookup.put(STCfType.NOT_CONTAINS_BLANKS, ConditionType.FILTER);

+        typeLookup.put(STCfType.CONTAINS_ERRORS, ConditionType.FILTER);

+        typeLookup.put(STCfType.NOT_CONTAINS_ERRORS, ConditionType.FILTER);

+        typeLookup.put(STCfType.TIME_PERIOD, ConditionType.FILTER);

+        typeLookup.put(STCfType.ABOVE_AVERAGE, ConditionType.FILTER);

+    }

+    

+    // TODO Support types beyond CELL_VALUE_IS and FORMULA

 

     /*package*/ XSSFConditionalFormattingRule(XSSFSheet sh){

         _cfRule = CTCfRule.Factory.newInstance();

@@ -149,23 +174,69 @@
 

         return new XSSFPatternFormatting(dxf.getFill());

     }

+    

+    public XSSFIconMultiStateFormatting createMultiStateFormatting(IconSet iconSet) {

+        // Is it already there?

+        if (_cfRule.isSetIconSet() && _cfRule.getType() == STCfType.ICON_SET)

+            return getMultiStateFormatting();

+        

+        // Mark it as being an Icon Set

+        _cfRule.setType(STCfType.ICON_SET);

+

+        // Ensure the right element

+        CTIconSet icons = null;

+        if (_cfRule.isSetIconSet()) {

+            icons = _cfRule.getIconSet();

+        } else {

+            icons = _cfRule.addNewIconSet();

+        }

+        // Set the type of the icon set

+        if (iconSet.name != null) {

+            STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(iconSet.name);

+            icons.setIconSet(xIconSet);

+        }

+        

+        // Add a default set of thresholds

+        int jump = 100 / iconSet.num;

+        STCfvoType.Enum type = STCfvoType.Enum.forString(RangeType.PERCENT.name);

+        for (int i=0; i<iconSet.num; i++) {

+            CTCfvo cfvo = icons.addNewCfvo();

+            cfvo.setType(type);

+            cfvo.setVal(Integer.toString(i*jump));

+        }

+        

+        // Wrap and return

+        return new XSSFIconMultiStateFormatting(icons);

+    }

+    public XSSFIconMultiStateFormatting getMultiStateFormatting() {

+        if (_cfRule.isSetIconSet()) {

+            CTIconSet icons = _cfRule.getIconSet();

+            return new XSSFIconMultiStateFormatting(icons);

+        } else {

+            return null;

+        }

+    }

 

     /**

      * Type of conditional formatting rule.

      * <p>

-     * MUST be either {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}

-     * or  {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA}

+     * MUST be one of the IDs of a {@link ConditionType}

      * </p>

      *

      * @return the type of condition

      */

     public byte getConditionType(){

-        switch (_cfRule.getType().intValue()){

-            case STCfType.INT_EXPRESSION: return ConditionalFormattingRule.CONDITION_TYPE_FORMULA;

-            case STCfType.INT_CELL_IS: return ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS;

-        }

+        ConditionType type = getConditionTypeType();

+        if (type != null) return type.id;

         return 0;

     }

+    

+    /**

+     * Type of conditional formatting rule.

+     */

+    public ConditionType getConditionTypeType() {

+        return typeLookup.get(_cfRule.getType());

+    }

 

     /**

      * The comparison function used when the type of conditional formatting is set to

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java
new file mode 100644
index 0000000..bfdd878
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java
@@ -0,0 +1,77 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+

+package org.apache.poi.xssf.usermodel;

+

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfvoType;

+

+/**

+ * High level representation for Icon / Multi-State / Databar /

+ *  Colour Scale change thresholds

+ */

+public class XSSFConditionalFormattingThreshold implements org.apache.poi.ss.usermodel.ConditionalFormattingThreshold {

+    private CTCfvo cfvo;

+    

+    protected XSSFConditionalFormattingThreshold(CTCfvo cfvo) {

+        this.cfvo = cfvo;

+    }

+    

+    protected CTCfvo getCTCfvo() {

+        return cfvo;

+    }

+

+    public RangeType getRangeType() {

+        return RangeType.byName(cfvo.getType().toString());

+    }

+    public void setRangeType(RangeType type) {

+        STCfvoType.Enum xtype = STCfvoType.Enum.forString(type.name);

+        cfvo.setType(xtype);

+    }

+

+    public String getFormula() {

+        if (cfvo.getType() == STCfvoType.FORMULA) {

+            return cfvo.getVal();

+        }

+        return null;

+    }

+    public void setFormula(String formula) {

+        cfvo.setVal(formula);

+    }

+

+    public Double getValue() {

+        if (cfvo.getType() == STCfvoType.FORMULA ||

+            cfvo.getType() == STCfvoType.MIN ||

+            cfvo.getType() == STCfvoType.MAX) {

+            return null;

+        }

+        if (cfvo.isSetVal()) {

+            return Double.parseDouble(cfvo.getVal());

+        } else {

+            return null;

+        }

+    }

+    public void setValue(Double value) {

+        if (value == null) {

+            cfvo.unsetVal();

+        } else {

+            cfvo.setVal(value.toString());

+        }

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java
index 00ac907..870c6c0 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataFormat.java
@@ -51,6 +51,14 @@
      * @return string represented at index of format or null if there is not a  format at that index
      */
     public String getFormat(short index) {
+        return getFormat(index&0xffff);
+    }
+    /**
+     * get the format string that matches the given format index
+     * @param index of a format
+     * @return string represented at index of format or null if there is not a  format at that index
+     */
+    public String getFormat(int index) {
         String fmt = stylesSource.getNumberFormatAt(index);
         if(fmt == null) fmt = BuiltinFormats.getBuiltinFormat(index);
         return fmt;
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java
index a5d8bdd..e788cf8 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java
@@ -80,7 +80,6 @@
         return (short)idx;

     }

 

-

     /**

      * @param color font color index

      */

@@ -91,16 +90,28 @@
         }

     }

 

-    /**

-     *

-     * @return xssf color wrapper or null if color info is missing

-     */

-    public XSSFColor getXSSFColor(){

+    public XSSFColor getFontColor() {

         if(_font.sizeOfColorArray() == 0) return null;

 

         return new XSSFColor(_font.getColorArray(0));

     }

 

+    public void setFontColor(Color color) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(color);

+        if (xcolor == null) {

+            _font.getColorList().clear();

+        } else {

+            _font.setColorArray(0, xcolor.getCTColor());

+        }

+    }

+

+    /**

+     * @deprecated use {@link #getFontColor()}

+     */

+    public XSSFColor getXSSFColor(){

+        return getFontColor();

+    }

+

     /**

      * gets the height of the font in 1/20th point units

      *

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java
new file mode 100644
index 0000000..81883bb
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java
@@ -0,0 +1,85 @@
+/*

+ *  ====================================================================

+ *    Licensed to the Apache Software Foundation (ASF) under one or more

+ *    contributor license agreements.  See the NOTICE file distributed with

+ *    this work for additional information regarding copyright ownership.

+ *    The ASF licenses this file to You under the Apache License, Version 2.0

+ *    (the "License"); you may not use this file except in compliance with

+ *    the License.  You may obtain a copy of the License at

+ *

+ *        http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *    Unless required by applicable law or agreed to in writing, software

+ *    distributed under the License is distributed on an "AS IS" BASIS,

+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *    See the License for the specific language governing permissions and

+ *    limitations under the License.

+ * ====================================================================

+ */

+package org.apache.poi.xssf.usermodel;

+

+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIconSet;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType;

+

+/**

+ * High level representation for Icon / Multi-State Formatting 

+ *  component of Conditional Formatting settings

+ */

+public class XSSFIconMultiStateFormatting implements IconMultiStateFormatting {

+    CTIconSet _iconset;

+

+    /*package*/ XSSFIconMultiStateFormatting(CTIconSet iconset){

+        _iconset = iconset;

+    }

+

+    public IconSet getIconSet() {

+        String set = _iconset.getIconSet().toString();

+        return IconSet.byName(set);

+    }

+    public void setIconSet(IconSet set) {

+        STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(set.name);

+        _iconset.setIconSet(xIconSet);

+    }

+

+    public boolean isIconOnly() {

+        if (_iconset.isSetShowValue())

+            return !_iconset.getShowValue();

+        return false;

+    }

+    public void setIconOnly(boolean only) {

+        _iconset.setShowValue(!only);

+    }

+

+    public boolean isReversed() {

+        if (_iconset.isSetReverse())

+            return _iconset.getReverse();

+        return false;

+    }

+    public void setReversed(boolean reversed) {

+        _iconset.setReverse(reversed);

+    }

+

+    @SuppressWarnings("deprecation")

+    public XSSFConditionalFormattingThreshold[] getThresholds() {

+        CTCfvo[] cfvos = _iconset.getCfvoArray();

+        XSSFConditionalFormattingThreshold[] t = 

+                new XSSFConditionalFormattingThreshold[cfvos.length];

+        for (int i=0; i<cfvos.length; i++) {

+            t[i] = new XSSFConditionalFormattingThreshold(cfvos[i]);

+        }

+        return t;

+    }

+    public void setThresholds(ConditionalFormattingThreshold[] thresholds) {

+        CTCfvo[] cfvos = new CTCfvo[thresholds.length];

+        for (int i=0; i<thresholds.length; i++) {

+            cfvos[i] = ((XSSFConditionalFormattingThreshold)thresholds[i]).getCTCfvo();

+        }

+        _iconset.setCfvoArray(cfvos);

+    }

+    public XSSFConditionalFormattingThreshold createThreshold() {

+        return new XSSFConditionalFormattingThreshold(_iconset.addNewCfvo());

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java
index f3d1329..3ca68f2 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java
@@ -18,6 +18,7 @@
  */

 package org.apache.poi.xssf.usermodel;

 

+import org.apache.poi.ss.usermodel.Color;

 import org.apache.poi.ss.usermodel.PatternFormatting;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill;

@@ -34,37 +35,69 @@
         _fill = fill;

     }

 

-    public short getFillBackgroundColor(){

-        if(!_fill.isSetPatternFill()) return 0;

-

-        return (short)_fill.getPatternFill().getBgColor().getIndexed();

+    public XSSFColor getFillBackgroundColorColor() {

+        if(!_fill.isSetPatternFill()) return null;

+        return new XSSFColor(_fill.getPatternFill().getBgColor());

     }

-

-    public short getFillForegroundColor(){

+    public XSSFColor getFillForegroundColorColor() {

         if(!_fill.isSetPatternFill() || ! _fill.getPatternFill().isSetFgColor())

-            return 0;

-

-        return (short)_fill.getPatternFill().getFgColor().getIndexed();

+            return null;

+        return new XSSFColor(_fill.getPatternFill().getFgColor());

     }

 

-    public short getFillPattern(){

+    public short getFillPattern() {

         if(!_fill.isSetPatternFill() || !_fill.getPatternFill().isSetPatternType()) return NO_FILL;

 

         return (short)(_fill.getPatternFill().getPatternType().intValue() - 1);

      }

 

-    public void setFillBackgroundColor(short bg){

-        CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();

-        CTColor bgColor = CTColor.Factory.newInstance();

-        bgColor.setIndexed(bg);

-        ptrn.setBgColor(bgColor);

+    public short getFillBackgroundColor() {

+        XSSFColor color = getFillBackgroundColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

+    }

+    public short getFillForegroundColor() {

+        XSSFColor color = getFillForegroundColorColor();

+        if (color == null) return 0;

+        return color.getIndexed();

     }

 

-    public void setFillForegroundColor(short fg){

+    public void setFillBackgroundColor(Color bg) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(bg);

+        if (xcolor == null) setFillBackgroundColor((CTColor)null);

+        else setFillBackgroundColor(xcolor.getCTColor());

+    }

+    public void setFillBackgroundColor(short bg) {

+        CTColor bgColor = CTColor.Factory.newInstance();

+        bgColor.setIndexed(bg);

+        setFillBackgroundColor(bgColor);

+    }

+    private void setFillBackgroundColor(CTColor color) {

         CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();

+        if (color == null) {

+            ptrn.unsetBgColor();

+        } else {

+            ptrn.setBgColor(color);

+        }

+    }

+    

+    public void setFillForegroundColor(Color fg) {

+        XSSFColor xcolor = XSSFColor.toXSSFColor(fg);

+        if (xcolor == null) setFillForegroundColor((CTColor)null);

+        else setFillForegroundColor(xcolor.getCTColor());

+    }

+    public void setFillForegroundColor(short fg) {

         CTColor fgColor = CTColor.Factory.newInstance();

         fgColor.setIndexed(fg);

-        ptrn.setFgColor(fgColor);

+        setFillForegroundColor(fgColor);

+    }

+    private void setFillForegroundColor(CTColor color) {

+        CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();

+        if (color == null) {

+            ptrn.unsetFgColor();

+        } else {

+            ptrn.setFgColor(color);

+        }

     }

 

     public void setFillPattern(short fp){

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java
index ecbbe8e..43b8c5a 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPrintSetup.java
@@ -120,6 +120,8 @@
     public void setLeftToRight(boolean ltor) {
         if (ltor)
             setPageOrder(PageOrder.OVER_THEN_DOWN);
+        else 
+            setPageOrder(PageOrder.DOWN_THEN_OVER);
     }
 
     /**
@@ -130,6 +132,8 @@
     public void setLandscape(boolean ls) {
         if (ls)
             setOrientation(PrintOrientation.LANDSCAPE);
+        else 
+            setOrientation(PrintOrientation.PORTRAIT);
     }
 
     /**
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
index 27caf13..fbe170f 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
@@ -281,7 +281,7 @@
         "application/vnd.ms-office.vbaProject",
         "http://schemas.microsoft.com/office/2006/relationships/vbaProject",
         "/xl/vbaProject.bin",
-        null
+        XSSFVBAPart.class
     );
 
     public static final XSSFRelation ACTIVEX_CONTROLS = new XSSFRelation(
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
index 6a48bf0..43140dc 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
@@ -25,11 +25,13 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedMap;
 import java.util.TreeMap;
 
 import javax.xml.namespace.QName;
@@ -131,7 +133,7 @@
     protected CTSheet sheet;
     protected CTWorksheet worksheet;
 
-    private TreeMap<Integer, XSSFRow> _rows;
+    private SortedMap<Integer, XSSFRow> _rows;
     private List<XSSFHyperlink> hyperlinks;
     private ColumnHelper columnHelper;
     private CommentsTable sheetComments;
@@ -140,7 +142,7 @@
      * Master shared formula is the first formula in a group of shared formulas is saved in the f element.
      */
     private Map<Integer, CTCellFormula> sharedFormulas;
-    private TreeMap<String,XSSFTable> tables;
+    private SortedMap<String,XSSFTable> tables;
     private List<CellRangeAddress> arrayFormulas;
     private XSSFDataValidationHelper dataValidationHelper;
 
@@ -600,6 +602,15 @@
         CTRow ctRow;
         XSSFRow prev = _rows.get(rownum);
         if(prev != null){
+            // the Cells in an existing row are invalidated on-purpose, in order to clean up correctly, we
+            // need to call the remove, so things like ArrayFormulas and CalculationChain updates are done 
+            // correctly. 
+            // We remove the cell this way as the internal cell-list is changed by the remove call and 
+            // thus would cause ConcurrentModificationException otherwise
+            while(prev.getFirstCellNum() != -1) {
+                prev.removeCell(prev.getCell(prev.getFirstCellNum()));
+            }
+            
             ctRow = prev.getCTRow();
             ctRow.set(CTRow.Factory.newInstance());
         } else {
@@ -1071,6 +1082,10 @@
     }
 
     /**
+     * Returns the merged region at the specified index. If you want multiple
+     * regions, it is faster to call {@link #getMergedRegions()} than to call
+     * this each time.
+     *
      * @return the merged region at the specified index
      * @throws IllegalStateException if this worksheet does not contain merged regions
      */
@@ -1085,6 +1100,27 @@
     }
 
     /**
+     * Returns the list of merged regions. If you want multiple regions, this is
+     * faster than calling {@link #getMergedRegion(int)} each time.
+     *
+     * @return the list of merged regions
+     * @throws IllegalStateException if this worksheet does not contain merged regions
+     */
+    @SuppressWarnings("deprecation")
+    @Override
+    public List<CellRangeAddress> getMergedRegions() {
+        CTMergeCells ctMergeCells = worksheet.getMergeCells();
+        if(ctMergeCells == null) throw new IllegalStateException("This worksheet does not contain merged regions");
+
+        List<CellRangeAddress> addresses = new ArrayList<CellRangeAddress>();
+        for(CTMergeCell ctMergeCell : ctMergeCells.getMergeCellArray()) {
+            String ref = ctMergeCell.getRef();
+            addresses.add(CellRangeAddress.valueOf(ref));
+        }
+        return addresses;
+    }
+
+    /**
      * Returns the number of merged regions defined in this worksheet
      *
      * @return number of merged regions in this worksheet
@@ -2555,38 +2591,90 @@
      */
     @Override
     @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
-    public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
-        // first remove all rows which will be overwritten
+    public void shiftRows(int startRow, int endRow, final int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
+    	XSSFVMLDrawing vml = getVMLDrawing(false);
+
+    	// first remove all rows which will be overwritten
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             XSSFRow row = (XSSFRow)it.next();
             int rownum = row.getRowNum();
 
             // check if we should remove this row as it will be overwritten by the data later
-            if (removeRow(startRow, endRow, n, rownum)) {
+            if (shouldRemoveRow(startRow, endRow, n, rownum)) {
                 // remove row from worksheet.getSheetData row array
                 int idx = _rows.headMap(row.getRowNum()).size();
                 worksheet.getSheetData().removeRow(idx);
+
                 // remove row from _rows
                 it.remove();
+
+                // also remove any comments associated with this row
+                if(sheetComments != null){
+                    CTCommentList lst = sheetComments.getCTComments().getCommentList();
+                    for (CTComment comment : lst.getCommentArray()) {
+                    	String strRef = comment.getRef();
+                    	CellReference ref = new CellReference(strRef);
+
+                    	// is this comment part of the current row?
+                    	if(ref.getRow() == rownum) {
+                            sheetComments.removeComment(strRef);
+                            vml.removeCommentShape(ref.getRow(), ref.getCol());
+                    	}
+                    }
+                }
             }
         }
 
         // then do the actual moving and also adjust comments/rowHeight
+        // we need to sort it in a way so the shifting does not mess up the structures, 
+        // i.e. when shifting down, start from down and go up, when shifting up, vice-versa
+        SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<XSSFComment, Integer>(new Comparator<XSSFComment>() {
+			public int compare(XSSFComment o1, XSSFComment o2) {
+				int row1 = o1.getRow();
+				int row2 = o2.getRow();
+				
+				if(row1 == row2) {
+					// ordering is not important when row is equal, but don't return zero to still 
+					// get multiple comments per row into the map
+					return o1.hashCode() - o2.hashCode();
+				}
+
+				// when shifting down, sort higher row-values first
+				if(n > 0) {
+					return row1 < row2 ? 1 : -1;
+				} else {
+					// sort lower-row values first when shifting up
+					return row1 > row2 ? 1 : -1;
+				}
+			}
+		});
+
+        
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             XSSFRow row = (XSSFRow)it.next();
             int rownum = row.getRowNum();
 
             if(sheetComments != null){
-                //TODO shift Note's anchor in the associated /xl/drawing/vmlDrawings#.vml
-                CTCommentList lst = sheetComments.getCTComments().getCommentList();
-                for (CTComment comment : lst.getCommentArray()) {
-                    String oldRef = comment.getRef();
-                    CellReference ref = new CellReference(oldRef);
-                    if(ref.getRow() == rownum){
-                        ref = new CellReference(rownum + n, ref.getCol());
-                        comment.setRef(ref.formatAsString());
-                        sheetComments.referenceUpdated(oldRef, comment);
-                    }
+            	// calculate the new rownum
+            	int newrownum = shiftedRowNum(startRow, endRow, n, rownum);
+            	
+            	// is there a change necessary for the current row?
+            	if(newrownum != rownum) {
+                    CTCommentList lst = sheetComments.getCTComments().getCommentList();
+                    for (CTComment comment : lst.getCommentArray()) {
+                    	String oldRef = comment.getRef();
+                    	CellReference ref = new CellReference(oldRef);
+                    	
+                    	// is this comment part of the current row?
+                    	if(ref.getRow() == rownum) {
+                        	XSSFComment xssfComment = new XSSFComment(sheetComments, comment,
+                                    vml == null ? null : vml.findCommentShape(rownum, ref.getCol()));
+                        	
+                        	// we should not perform the shifting right here as we would then find
+                        	// already shifted comments and would shift them again...
+                        	commentsToShift.put(xssfComment, newrownum);
+                        }
+                	}
                 }
             }
 
@@ -2598,6 +2686,14 @@
 
             row.shift(n);
         }
+        
+        // adjust all the affected comment-structures now
+        // the Map is sorted and thus provides them in the order that we need here, 
+        // i.e. from down to up if shifting down, vice-versa otherwise
+        for(Map.Entry<XSSFComment, Integer> entry : commentsToShift.entrySet()) {
+        	entry.getKey().setRow(entry.getValue());
+        }
+        
         XSSFRowShifter rowShifter = new XSSFRowShifter(this);
 
         int sheetIndex = getWorkbook().getSheetIndex(this);
@@ -2611,13 +2707,40 @@
         rowShifter.updateConditionalFormatting(shifter);
 
         //rebuild the _rows map
-        TreeMap<Integer, XSSFRow> map = new TreeMap<Integer, XSSFRow>();
+        SortedMap<Integer, XSSFRow> map = new TreeMap<Integer, XSSFRow>();
         for(XSSFRow r : _rows.values()) {
             map.put(r.getRowNum(), r);
         }
         _rows = map;
     }
 
+    private int shiftedRowNum(int startRow, int endRow, int n, int rownum) {
+		// no change if before any affected row
+    	if(rownum < startRow && (n > 0 || (startRow - rownum) > n)) {
+			return rownum;
+		}
+		
+    	// no change if after any affected row
+    	if(rownum > endRow && (n < 0 || (rownum - endRow) > n)) {
+    		return rownum;
+    	}
+    	
+    	// row before and things are moved up
+    	if(rownum < startRow) {
+    		// row is moved down by the shifting
+    		return rownum + (endRow - startRow);
+    	}
+    	
+    	// row is after and things are moved down
+    	if(rownum > endRow) {
+    		// row is moved up by the shifting
+    		return rownum - (endRow - startRow);
+    	}
+    	
+    	// row is part of the shifted block
+		return rownum + n;
+	}
+
     /**
      * Location of the top left visible cell Location of the top left visible cell in the bottom right
      * pane (when in Left-to-Right mode).
@@ -2873,7 +2996,7 @@
         return sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
     }
 
-    private boolean removeRow(int startRow, int endRow, int n, int rownum) {
+    private boolean shouldRemoveRow(int startRow, int endRow, int n, int rownum) {
         // is this row in the target-window where the moved rows will land?
         if (rownum >= (startRow + n) && rownum <= (endRow + n)) {
             // only remove it if the current row is not part of the data that is copied
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
index 8c83f6f..afd8885 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
@@ -27,6 +27,7 @@
 import org.apache.poi.ss.usermodel.ComparisonOperator;

 import org.apache.poi.ss.usermodel.ConditionalFormatting;

 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;

 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;

 import org.apache.poi.ss.util.CellRangeAddress;

 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;

@@ -36,9 +37,12 @@
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;

 

 /**

- * @author Yegor Kozlov

+ * XSSF Conditional Formattings

  */

 public class XSSFSheetConditionalFormatting implements SheetConditionalFormatting {

+    /** Office 2010 Conditional Formatting extensions namespace */

+    protected static final String CF_EXT_2009_NS_X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main";

+

     private final XSSFSheet _sheet;

 

     /* package */ XSSFSheetConditionalFormatting(XSSFSheet sheet) {

@@ -115,6 +119,27 @@
         return rule;

     }

 

+    /**

+     * A factory method allowing the creation of conditional formatting

+     *  rules using an Icon Set / Multi-State formatting.

+     * The thresholds for it will be created, but will be empty

+     *  and require configuring with 

+     *  {@link XSSFConditionalFormattingRule#getMultiStateFormatting()}

+     *  then

+     *  {@link XSSFIconMultiStateFormatting#getThresholds()}

+     */

+    public XSSFConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet) {

+        XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet);

+        

+        // Have it setup, with suitable defaults

+        rule.createMultiStateFormatting(iconSet);

+        

+        // All done!

+        return rule;

+    }

+

+    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs

+    

     @SuppressWarnings("deprecation")

     public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {

         if (regions == null) {

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java
index c89d0cd..6500c16 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java
@@ -709,13 +709,19 @@
     public boolean isBullet() {
         ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){
             public boolean fetch(CTTextParagraphProperties props){
-                if(props.isSetBuNone()) {
+                if (props.isSetBuNone()) {
                     setValue(false);
                     return true;
                 }
-                if(props.isSetBuFont() || props.isSetBuChar() || props.isSetBuAutoNum()){
-                    setValue(true);
-                    return true;
+                if (props.isSetBuFont()) {
+                    if (props.isSetBuChar() || props.isSetBuAutoNum()) {
+                        setValue(true);
+                        return true;
+                    } else {
+                        // Excel treats text with buFont but no char/autonum
+                        //  as not bulleted
+                        // Possibly the font is just used if bullets turned on again?
+                    }
                 }
                 return false;
             }
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java
new file mode 100644
index 0000000..263dae0
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java
@@ -0,0 +1,52 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xssf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+
+public class XSSFVBAPart extends POIXMLDocumentPart {
+
+    /**
+     * Create a new XSSFVBAPart node
+     */
+    protected XSSFVBAPart() {
+        super();
+    }
+
+    /**
+     * Construct XSSFVBAPart from a package part
+     *
+     * @param part the package part holding the VBA data,
+     * @param rel  the package relationship holding this part
+     */
+    protected XSSFVBAPart(PackagePart part, PackageRelationship rel) {
+        super(part, rel);
+    }
+
+    /**
+     * Like *PictureData, VBA objects store the actual content in the part
+     * directly without keeping a copy like all others therefore we need to
+     * handle them differently.
+     */
+    protected void prepareForCommit() {
+        // do not clear the part here
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java
index a145866..75f292f 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java
@@ -68,6 +68,7 @@
     private static final QName QNAME_SHAPE_LAYOUT = new QName("urn:schemas-microsoft-com:office:office", "shapelayout");
     private static final QName QNAME_SHAPE_TYPE = new QName("urn:schemas-microsoft-com:vml", "shapetype");
     private static final QName QNAME_SHAPE = new QName("urn:schemas-microsoft-com:vml", "shape");
+    private static final String COMMENT_SHAPE_TYPE_ID = "_x0000_t202"; // this ID value seems to have significance to Excel >= 2010; see https://issues.apache.org/bugzilla/show_bug.cgi?id=55409
 
     /**
      * regexp to parse shape ids, in VML they have weird form of id="_x0000_s1026"
@@ -190,7 +191,7 @@
         _qnames.add(QNAME_SHAPE_LAYOUT);
 
         CTShapetype shapetype = CTShapetype.Factory.newInstance();
-        _shapeTypeId = "_xssf_cell_comment";
+        _shapeTypeId = COMMENT_SHAPE_TYPE_ID;
         shapetype.setId(_shapeTypeId);
         shapetype.setCoordsize("21600,21600");
         shapetype.setSpt(202);
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index ae09af1..f90b48d 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -215,7 +215,15 @@
      * Create a new SpreadsheetML workbook.
      */
     public XSSFWorkbook() {
-        super(newPackage());
+        this(XSSFWorkbookType.XLSX);
+    }
+
+    /**
+     * Create a new SpreadsheetML workbook.
+     * @param workbookType The type of workbook to make (.xlsx or .xlsm).
+     */
+    public XSSFWorkbook(XSSFWorkbookType workbookType) {
+        super(newPackage(workbookType));
         onWorkbookCreate();
     }
 
@@ -429,7 +437,7 @@
     /**
      * Create a new SpreadsheetML package and setup the default minimal content
      */
-    protected static OPCPackage newPackage() {
+    protected static OPCPackage newPackage(XSSFWorkbookType workbookType) {
         try {
             OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
             // Main part
@@ -437,7 +445,7 @@
             // Create main part relationship
             pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
             // Create main document part
-            pkg.createPart(corePartName, XSSFRelation.WORKBOOK.getContentType());
+            pkg.createPart(corePartName, workbookType.getContentType());
 
             pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
 
@@ -576,13 +584,17 @@
             // copy drawing contents
             clonedDg.getCTDrawing().set(dg.getCTDrawing());
 
+            clonedDg = clonedSheet.createDrawingPatriarch();
+            
             // Clone drawing relations
             List<POIXMLDocumentPart> srcRels = srcSheet.createDrawingPatriarch().getRelations();
             for (POIXMLDocumentPart rel : srcRels) {
                 PackageRelationship relation = rel.getPackageRelationship();
-                clonedSheet
-                        .createDrawingPatriarch()
-                        .getPackagePart()
+
+                clonedDg.addRelation(relation.getId(), rel);
+                
+                clonedDg
+						.getPackagePart()
                         .addRelationship(relation.getTargetURI(), relation.getTargetMode(),
                                 relation.getRelationshipType(), relation.getId());
             }
@@ -751,8 +763,26 @@
         CTSheet sheet = addSheet(sheetname);
 
         int sheetNumber = 1;
-        for(XSSFSheet sh : sheets) {
-            sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber);
+        outerloop:
+        while(true) {
+            for(XSSFSheet sh : sheets) {
+                sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber);
+            }
+            
+            // Bug 57165: We also need to check that the resulting file name is not already taken
+            // this can happen when moving/cloning sheets
+            String sheetName = XSSFRelation.WORKSHEET.getFileName(sheetNumber);
+            for(POIXMLDocumentPart relation : getRelations()) {
+                if(relation.getPackagePart() != null && 
+                        sheetName.equals(relation.getPackagePart().getPartName().getName())) {
+                    // name is taken => try next one
+                    sheetNumber++;
+                    continue outerloop;
+                }
+            }
+
+            // no duplicate found => use this one
+            break;
         }
 
         XSSFSheet wrapper = (XSSFSheet)createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber);
@@ -821,6 +851,15 @@
      */
     @Override
     public XSSFCellStyle getCellStyleAt(short idx) {
+        return getCellStyleAt(idx&0xffff);
+    }
+    /**
+     * Get the cell style object at the given index
+     *
+     * @param idx  index within the set of styles
+     * @return XSSFCellStyle object at the index
+     */
+    public XSSFCellStyle getCellStyleAt(int idx) {
         return stylesSource.getStyleAt(idx);
     }
 
@@ -1518,16 +1557,6 @@
     }
     
     /**
-     * Closes the underlying {@link OPCPackage} from which
-     *  the Workbook was read, if any. Has no effect on newly 
-     *  created Workbooks.
-     */
-    @Override
-    public void close() throws IOException {
-        super.close();
-    }
-
-    /**
      * Returns SharedStringsTable - tha cache of string for this workbook
      *
      * @return the shared string table
@@ -2023,4 +2052,67 @@
     protected void setPivotTables(List<XSSFPivotTable> pivotTables) {
         this.pivotTables = pivotTables;
     }
+
+    public XSSFWorkbookType getWorkbookType() {
+        return isMacroEnabled() ? XSSFWorkbookType.XLSM : XSSFWorkbookType.XLSX;
+    }
+
+    /**
+     * Sets whether the workbook will be an .xlsx or .xlsm (macro-enabled) file.
+     */
+    public void setWorkbookType(XSSFWorkbookType type) {
+        try {
+            getPackagePart().setContentType(type.getContentType());
+        } catch (InvalidFormatException e) {
+            throw new POIXMLException(e);
+        }
+    }
+
+    /**
+     * Adds a vbaProject.bin file to the workbook.  This will change the workbook
+     * type if necessary.
+     *
+     * @throws IOException
+     */
+    public void setVBAProject(InputStream vbaProjectStream) throws IOException {
+        if (!isMacroEnabled()) {
+            setWorkbookType(XSSFWorkbookType.XLSM);
+        }
+
+        PackagePartName ppName;
+        try {
+            ppName = PackagingURIHelper.createPartName(XSSFRelation.VBA_MACROS.getDefaultFileName());
+        } catch (InvalidFormatException e) {
+            throw new POIXMLException(e);
+        }
+        OPCPackage opc = getPackage();
+        OutputStream outputStream;
+        if (!opc.containPart(ppName)) {
+            POIXMLDocumentPart relationship = createRelationship(XSSFRelation.VBA_MACROS, XSSFFactory.getInstance());
+            outputStream = relationship.getPackagePart().getOutputStream();
+        } else {
+            PackagePart part = opc.getPart(ppName);
+            outputStream = part.getOutputStream();
+        }
+        try {
+            IOUtils.copy(vbaProjectStream, outputStream);
+        } finally {
+            IOUtils.closeQuietly(outputStream);
+        }
+    }
+
+    /**
+     * Adds a vbaProject.bin file taken from another, given workbook to this one.
+     * @throws IOException
+     * @throws InvalidFormatException
+     */
+    public void setVBAProject(XSSFWorkbook macroWorkbook) throws IOException, InvalidFormatException {
+        if (!macroWorkbook.isMacroEnabled()) {
+            return;
+        }
+        InputStream vbaProjectStream = XSSFRelation.VBA_MACROS.getContents(macroWorkbook.getCorePart());
+        if (vbaProjectStream != null) {
+            setVBAProject(vbaProjectStream);
+        }
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java
new file mode 100644
index 0000000..917d3d6
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookType.java
@@ -0,0 +1,45 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xssf.usermodel;
+
+
+/**
+ * Represents the two different kinds of XML-based OOXML document.
+ */
+public enum XSSFWorkbookType {
+
+    XLSX(XSSFRelation.WORKBOOK.getContentType(), "xlsx"),
+    XLSM(XSSFRelation.MACROS_WORKBOOK.getContentType(), "xlsm");
+
+    private final String _contentType;
+    private final String _extension;
+
+    private XSSFWorkbookType(String contentType, String extension) {
+        _contentType = contentType;
+        _extension = extension;
+    }
+
+    public String getContentType() {
+        return _contentType;
+    }
+
+    public String getExtension() {
+        return _extension;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java
index 776210d..a9d995f 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java
@@ -24,6 +24,7 @@
 import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.Pxg;
+import org.apache.poi.ss.formula.ptg.Pxg3D;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -125,9 +126,17 @@
         if (ptg instanceof Pxg) {
             Pxg pxg = (Pxg)ptg;
             if (pxg.getExternalWorkbookNumber() < 1) {
-                if (pxg.getSheetName().equals(oldName)) {
+                if (pxg.getSheetName() != null &&
+                        pxg.getSheetName().equals(oldName)) {
                     pxg.setSheetName(newName);
                 }
+                if (pxg instanceof Pxg3D) {
+                    Pxg3D pxg3D = (Pxg3D)pxg;
+                    if (pxg3D.getLastSheetName() != null &&
+                            pxg3D.getLastSheetName().equals(oldName)) {
+                        pxg3D.setLastSheetName(newName);
+                    }
+                }
             }
         }
     }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java b/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java
index afff770..ec701b7 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java
@@ -46,46 +46,47 @@
  * Helper class to extract text from an OOXML Word file
  */
 public class XWPFWordExtractor extends POIXMLTextExtractor {
-   public static final XWPFRelation[] SUPPORTED_TYPES = new XWPFRelation[] {
-      XWPFRelation.DOCUMENT, XWPFRelation.TEMPLATE,
-      XWPFRelation.MACRO_DOCUMENT, 
-      XWPFRelation.MACRO_TEMPLATE_DOCUMENT
-   };
-   
-	private XWPFDocument document;
-	private boolean fetchHyperlinks = false;
-	
-	public XWPFWordExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
-		this(new XWPFDocument(container));
-	}
-	public XWPFWordExtractor(XWPFDocument document) {
-		super(document);
-		this.document = document;
-	}
+    public static final XWPFRelation[] SUPPORTED_TYPES = new XWPFRelation[]{
+            XWPFRelation.DOCUMENT, XWPFRelation.TEMPLATE,
+            XWPFRelation.MACRO_DOCUMENT,
+            XWPFRelation.MACRO_TEMPLATE_DOCUMENT
+    };
 
-	/**
-	 * Should we also fetch the hyperlinks, when fetching 
-	 *  the text content? Default is to only output the
-	 *  hyperlink label, and not the contents
-	 */
-	public void setFetchHyperlinks(boolean fetch) {
-		fetchHyperlinks = fetch;
-	}
-	
-	public static void main(String[] args) throws Exception {
-		if(args.length < 1) {
-			System.err.println("Use:");
-			System.err.println("  XWPFWordExtractor <filename.docx>");
-			System.exit(1);
-		}
-		POIXMLTextExtractor extractor = 
-			new XWPFWordExtractor(POIXMLDocument.openPackage(
-					args[0]
-			));
-		System.out.println(extractor.getText());
-		extractor.close();
-	}
-	
+    private XWPFDocument document;
+    private boolean fetchHyperlinks = false;
+
+    public XWPFWordExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
+        this(new XWPFDocument(container));
+    }
+
+    public XWPFWordExtractor(XWPFDocument document) {
+        super(document);
+        this.document = document;
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 1) {
+            System.err.println("Use:");
+            System.err.println("  XWPFWordExtractor <filename.docx>");
+            System.exit(1);
+        }
+        POIXMLTextExtractor extractor =
+                new XWPFWordExtractor(POIXMLDocument.openPackage(
+                        args[0]
+                ));
+        System.out.println(extractor.getText());
+        extractor.close();
+    }
+
+    /**
+     * Should we also fetch the hyperlinks, when fetching
+     * the text content? Default is to only output the
+     * hyperlink label, and not the contents
+     */
+    public void setFetchHyperlinks(boolean fetch) {
+        fetchHyperlinks = fetch;
+    }
+
     public String getText() {
         StringBuffer text = new StringBuffer();
         XWPFHeaderFooterPolicy hfPolicy = document.getHeaderFooterPolicy();
@@ -94,9 +95,9 @@
         extractHeaders(text, hfPolicy);
 
         // Process all body elements
-        for (IBodyElement e : document.getBodyElements()){
-        	appendBodyElementText(text, e);
-        	text.append('\n');
+        for (IBodyElement e : document.getBodyElements()) {
+            appendBodyElementText(text, e);
+            text.append('\n');
         }
 
         // Finish up with all the footers
@@ -105,108 +106,108 @@
         return text.toString();
     }
 
-   public void appendBodyElementText(StringBuffer text, IBodyElement e){
-      if (e instanceof XWPFParagraph){
-          appendParagraphText(text, (XWPFParagraph)e);
-      } else if (e instanceof XWPFTable){
-          appendTableText(text, (XWPFTable)e);
-      } else if (e instanceof XWPFSDT){
-          text.append(((XWPFSDT)e).getContent().getText());
-      }
-   }
-   
-   public void appendParagraphText(StringBuffer text, XWPFParagraph paragraph){
-      try {
-          CTSectPr ctSectPr = null;
-          if (paragraph.getCTP().getPPr()!=null) {
-              ctSectPr = paragraph.getCTP().getPPr().getSectPr();
-          }
+    public void appendBodyElementText(StringBuffer text, IBodyElement e) {
+        if (e instanceof XWPFParagraph) {
+            appendParagraphText(text, (XWPFParagraph) e);
+        } else if (e instanceof XWPFTable) {
+            appendTableText(text, (XWPFTable) e);
+        } else if (e instanceof XWPFSDT) {
+            text.append(((XWPFSDT) e).getContent().getText());
+        }
+    }
 
-          XWPFHeaderFooterPolicy headerFooterPolicy = null;
+    public void appendParagraphText(StringBuffer text, XWPFParagraph paragraph) {
+        try {
+            CTSectPr ctSectPr = null;
+            if (paragraph.getCTP().getPPr() != null) {
+                ctSectPr = paragraph.getCTP().getPPr().getSectPr();
+            }
 
-          if (ctSectPr!=null) {
-              headerFooterPolicy = new XWPFHeaderFooterPolicy(document, ctSectPr);
-              extractHeaders(text, headerFooterPolicy);
-          }
+            XWPFHeaderFooterPolicy headerFooterPolicy = null;
+
+            if (ctSectPr != null) {
+                headerFooterPolicy = new XWPFHeaderFooterPolicy(document, ctSectPr);
+                extractHeaders(text, headerFooterPolicy);
+            }
 
 
-          for(IRunElement run : paragraph.getRuns()) {
-              text.append(run.toString());
-              if(run instanceof XWPFHyperlinkRun && fetchHyperlinks) {
-                  XWPFHyperlink link = ((XWPFHyperlinkRun)run).getHyperlink(document);
-                  if(link != null)
-                      text.append(" <" + link.getURL() + ">");
-              }
-          }
+            for (IRunElement run : paragraph.getRuns()) {
+                text.append(run.toString());
+                if (run instanceof XWPFHyperlinkRun && fetchHyperlinks) {
+                    XWPFHyperlink link = ((XWPFHyperlinkRun) run).getHyperlink(document);
+                    if (link != null)
+                        text.append(" <" + link.getURL() + ">");
+                }
+            }
 
-          // Add comments
-          XWPFCommentsDecorator decorator = new XWPFCommentsDecorator(paragraph, null);
-          String commentText = decorator.getCommentText();
-          if (commentText.length() > 0){
-              text.append(commentText).append('\n');
-          }
+            // Add comments
+            XWPFCommentsDecorator decorator = new XWPFCommentsDecorator(paragraph, null);
+            String commentText = decorator.getCommentText();
+            if (commentText.length() > 0) {
+                text.append(commentText).append('\n');
+            }
 
-          // Do endnotes and footnotes
-          String footnameText = paragraph.getFootnoteText();
-          if(footnameText != null && footnameText.length() > 0) {
-              text.append(footnameText + '\n');
-          }
+            // Do endnotes and footnotes
+            String footnameText = paragraph.getFootnoteText();
+            if (footnameText != null && footnameText.length() > 0) {
+                text.append(footnameText + '\n');
+            }
 
-          if (ctSectPr!=null) {
-              extractFooters(text, headerFooterPolicy);
-          }
-      } catch (IOException e) {
-          throw new POIXMLException(e);
-      } catch (XmlException e) {
-          throw new POIXMLException(e);
-      }
-     
-   }
+            if (ctSectPr != null) {
+                extractFooters(text, headerFooterPolicy);
+            }
+        } catch (IOException e) {
+            throw new POIXMLException(e);
+        } catch (XmlException e) {
+            throw new POIXMLException(e);
+        }
 
-   private void appendTableText(StringBuffer text, XWPFTable table) {
-      //this works recursively to pull embedded tables from tables
-      for (XWPFTableRow row : table.getRows()) {
-          List<ICell> cells = row.getTableICells();
-          for (int i = 0; i < cells.size(); i++) {
-              ICell cell = cells.get(i);
-              if (cell instanceof XWPFTableCell) {
-                  text.append(((XWPFTableCell)cell).getTextRecursively());
-              } else if (cell instanceof XWPFSDTCell) {
-                  text.append(((XWPFSDTCell)cell).getContent().getText());
-              }
-              if (i < cells.size()-1) {
-                  text.append("\t");
-              }
-          }
-          text.append('\n');
-      }
-   }
-   
-	private void extractFooters(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) {
-		if (hfPolicy == null) return;
-		
-		if(hfPolicy.getFirstPageFooter() != null) {
-			text.append( hfPolicy.getFirstPageFooter().getText() );
-		}
-		if(hfPolicy.getEvenPageFooter() != null) {
-			text.append( hfPolicy.getEvenPageFooter().getText() );
-		}
-		if(hfPolicy.getDefaultFooter() != null) {
-			text.append( hfPolicy.getDefaultFooter().getText() );
-		}
-	}
+    }
 
-	private void extractHeaders(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) {
-		if (hfPolicy == null) return;
-		
-		if(hfPolicy.getFirstPageHeader() != null) {
-			text.append( hfPolicy.getFirstPageHeader().getText() );
-		}
-		if(hfPolicy.getEvenPageHeader() != null) {
-			text.append( hfPolicy.getEvenPageHeader().getText() );
-		}
-		if(hfPolicy.getDefaultHeader() != null) {
-			text.append( hfPolicy.getDefaultHeader().getText() );
-		}
-	}
+    private void appendTableText(StringBuffer text, XWPFTable table) {
+        //this works recursively to pull embedded tables from tables
+        for (XWPFTableRow row : table.getRows()) {
+            List<ICell> cells = row.getTableICells();
+            for (int i = 0; i < cells.size(); i++) {
+                ICell cell = cells.get(i);
+                if (cell instanceof XWPFTableCell) {
+                    text.append(((XWPFTableCell) cell).getTextRecursively());
+                } else if (cell instanceof XWPFSDTCell) {
+                    text.append(((XWPFSDTCell) cell).getContent().getText());
+                }
+                if (i < cells.size() - 1) {
+                    text.append("\t");
+                }
+            }
+            text.append('\n');
+        }
+    }
+
+    private void extractFooters(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) {
+        if (hfPolicy == null) return;
+
+        if (hfPolicy.getFirstPageFooter() != null) {
+            text.append(hfPolicy.getFirstPageFooter().getText());
+        }
+        if (hfPolicy.getEvenPageFooter() != null) {
+            text.append(hfPolicy.getEvenPageFooter().getText());
+        }
+        if (hfPolicy.getDefaultFooter() != null) {
+            text.append(hfPolicy.getDefaultFooter().getText());
+        }
+    }
+
+    private void extractHeaders(StringBuffer text, XWPFHeaderFooterPolicy hfPolicy) {
+        if (hfPolicy == null) return;
+
+        if (hfPolicy.getFirstPageHeader() != null) {
+            text.append(hfPolicy.getFirstPageHeader().getText());
+        }
+        if (hfPolicy.getEvenPageHeader() != null) {
+            text.append(hfPolicy.getEvenPageHeader().getText());
+        }
+        if (hfPolicy.getDefaultHeader() != null) {
+            text.append(hfPolicy.getDefaultHeader().getText());
+        }
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java
index c7d4bc2..25aa7aa 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XMLParagraph.java
@@ -22,16 +22,15 @@
  * Base class for XWPF paragraphs
  *
  * @author Yury Batrakov (batrakov at gmail.com)
- * 
  */
 public class XMLParagraph {
-	protected CTP paragraph;
-	
-	public XMLParagraph(CTP paragraph) {
-		this.paragraph = paragraph;
-	}
+    protected CTP paragraph;
 
-	public CTP getCTP() {
-		return paragraph;
-	}
+    public XMLParagraph(CTP paragraph) {
+        this.paragraph = paragraph;
+    }
+
+    public CTP getCTP() {
+        return paragraph;
+    }
 }
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
index 502a3b7..bf2b5e8 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
@@ -21,38 +21,36 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange;
 
 /**
- * Decorator class for XWPFParagraph allowing to add comments 
+ * Decorator class for XWPFParagraph allowing to add comments
  * found in paragraph to its text
  *
  * @author Yury Batrakov (batrakov at gmail.com)
- * 
  */
 public class XWPFCommentsDecorator extends XWPFParagraphDecorator {
-	private StringBuffer commentText;
-	
-	public XWPFCommentsDecorator(XWPFParagraphDecorator nextDecorator) {
-		this(nextDecorator.paragraph, nextDecorator);
-	}
+    private StringBuffer commentText;
 
-	@SuppressWarnings("deprecation")
-	public XWPFCommentsDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) {
-		super(paragraph, nextDecorator);
+    public XWPFCommentsDecorator(XWPFParagraphDecorator nextDecorator) {
+        this(nextDecorator.paragraph, nextDecorator);
+    }
 
-		XWPFComment comment;
-		commentText = new StringBuffer();
+    @SuppressWarnings("deprecation")
+    public XWPFCommentsDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) {
+        super(paragraph, nextDecorator);
 
-		for(CTMarkupRange anchor : paragraph.getCTP().getCommentRangeStartArray())
-		{
-			if((comment = paragraph.getDocument().getCommentByID(anchor.getId().toString())) != null)
-				commentText.append("\tComment by " + comment.getAuthor()+": "+comment.getText());
-		}
-	}
+        XWPFComment comment;
+        commentText = new StringBuffer();
 
-	public String getCommentText() {
-	   return commentText.toString();
-	}
-	
-	public String getText() {
-		return super.getText() + commentText;
-	}
+        for (CTMarkupRange anchor : paragraph.getCTP().getCommentRangeStartArray()) {
+            if ((comment = paragraph.getDocument().getCommentByID(anchor.getId().toString())) != null)
+                commentText.append("\tComment by " + comment.getAuthor() + ": " + comment.getText());
+        }
+    }
+
+    public String getCommentText() {
+        return commentText.toString();
+    }
+
+    public String getText() {
+        return super.getText() + commentText;
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
index 1578316..700645d 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
@@ -45,7 +45,6 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr.Enum;
-
 import schemasMicrosoftComOfficeOffice.CTLock;
 import schemasMicrosoftComOfficeOffice.STConnectType;
 import schemasMicrosoftComVml.CTFormulas;
@@ -61,10 +60,10 @@
 
 /**
  * A .docx file can have no headers/footers, the same header/footer
- *  on each page, odd/even page footers, and optionally also 
- *  a different header/footer on the first page.
+ * on each page, odd/even page footers, and optionally also
+ * a different header/footer on the first page.
  * This class handles sorting out what there is, and giving you
- *  the right headers and footers for the document.
+ * the right headers and footers for the document.
  */
 public class XWPFHeaderFooterPolicy {
     public static final Enum DEFAULT = STHdrFtr.DEFAULT;
@@ -84,8 +83,8 @@
 
     /**
      * Figures out the policy for the given document,
-     *  and creates any header and footer objects
-     *  as required.
+     * and creates any header and footer objects
+     * as required.
      */
     public XWPFHeaderFooterPolicy(XWPFDocument doc) throws IOException, XmlException {
         this(doc, doc.getDocument().getBody().getSectPr());
@@ -93,8 +92,8 @@
 
     /**
      * Figures out the policy for the given document,
-     *  and creates any header and footer objects
-     *  as required.
+     * and creates any header and footer objects
+     * as required.
      */
     public XWPFHeaderFooterPolicy(XWPFDocument doc, CTSectPr sectPr) throws IOException, XmlException {
         // Grab what headers and footers have been defined
@@ -102,7 +101,7 @@
         //  doesn't seem that .docx properly supports that
         //  feature of the file format yet
         this.doc = doc;
-        for(int i=0; i<sectPr.sizeOfHeaderReferenceArray(); i++) {
+        for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) {
             // Get the header
             CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
             POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId());
@@ -114,13 +113,12 @@
             Enum type = ref.getType();
             assignHeader(hdr, type);
         }
-        for(int i=0; i<sectPr.sizeOfFooterReferenceArray(); i++) {
+        for (int i = 0; i < sectPr.sizeOfFooterReferenceArray(); i++) {
             // Get the footer
             CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i);
             POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId());
             XWPFFooter ftr = null;
-            if (relatedPart != null && relatedPart instanceof XWPFFooter)
-            {
+            if (relatedPart != null && relatedPart instanceof XWPFFooter) {
                 ftr = (XWPFFooter) relatedPart;
             }
             // Assign it
@@ -130,9 +128,9 @@
     }
 
     private void assignFooter(XWPFFooter ftr, Enum type) {
-        if(type == STHdrFtr.FIRST) {
+        if (type == STHdrFtr.FIRST) {
             firstPageFooter = ftr;
-        } else if(type == STHdrFtr.EVEN) {
+        } else if (type == STHdrFtr.EVEN) {
             evenPageFooter = ftr;
         } else {
             defaultFooter = ftr;
@@ -140,9 +138,9 @@
     }
 
     private void assignHeader(XWPFHeader hdr, Enum type) {
-        if(type == STHdrFtr.FIRST) {
+        if (type == STHdrFtr.FIRST) {
             firstPageHeader = hdr;
-        } else if(type == STHdrFtr.EVEN) {
+        } else if (type == STHdrFtr.EVEN) {
             evenPageHeader = hdr;
         } else {
             defaultHeader = hdr;
@@ -159,15 +157,15 @@
 
     /**
      * Creates a new header of the specified type, to which the
-     *  supplied (and previously unattached!) paragraphs are
-     *  added to.
+     * supplied (and previously unattached!) paragraphs are
+     * added to.
      */
     public XWPFHeader createHeader(Enum type, XWPFParagraph[] pars) throws IOException {
         XWPFRelation relation = XWPFRelation.HEADER;
         String pStyle = "Header";
         int i = getRelationIndex(relation);
         HdrDocument hdrDoc = HdrDocument.Factory.newInstance();
-        XWPFHeader wrapper = (XWPFHeader)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
+        XWPFHeader wrapper = (XWPFHeader) doc.createRelationship(relation, XWPFFactory.getInstance(), i);
 
         CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars);
         wrapper.setHeaderFooter(hdr);
@@ -193,15 +191,15 @@
 
     /**
      * Creates a new footer of the specified type, to which the
-     *  supplied (and previously unattached!) paragraphs are
-     *  added to.
+     * supplied (and previously unattached!) paragraphs are
+     * added to.
      */
     public XWPFFooter createFooter(Enum type, XWPFParagraph[] pars) throws IOException {
         XWPFRelation relation = XWPFRelation.FOOTER;
         String pStyle = "Footer";
         int i = getRelationIndex(relation);
         FtrDocument ftrDoc = FtrDocument.Factory.newInstance();
-        XWPFFooter wrapper = (XWPFFooter)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
+        XWPFFooter wrapper = (XWPFFooter) doc.createRelationship(relation, XWPFFactory.getInstance(), i);
 
         CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);
         wrapper.setHeaderFooter(ftr);
@@ -220,10 +218,10 @@
     private int getRelationIndex(XWPFRelation relation) {
         List<POIXMLDocumentPart> relations = doc.getRelations();
         int i = 1;
-        for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext() ; ) {
+        for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext(); ) {
             POIXMLDocumentPart item = it.next();
             if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
-                i++;	
+                i++;
             }
         }
         return i;
@@ -231,14 +229,14 @@
 
     private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) {
         //CTHdrFtr ftr = buildHdrFtr(pStyle, pars);				// MB 24 May 2010
-        CTHdrFtr ftr = buildHdrFtr(pStyle, pars, wrapper);		// MB 24 May 2010
+        CTHdrFtr ftr = buildHdrFtr(pStyle, pars, wrapper);        // MB 24 May 2010
         setFooterReference(type, wrapper);
         return ftr;
     }
 
     private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) {
         //CTHdrFtr hdr = buildHdrFtr(pStyle, pars);				// MB 24 May 2010
-        CTHdrFtr hdr = buildHdrFtr(pStyle, pars, wrapper);		// MB 24 May 2010
+        CTHdrFtr hdr = buildHdrFtr(pStyle, pars, wrapper);        // MB 24 May 2010
         setHeaderReference(type, wrapper);
         return hdr;
     }
@@ -246,13 +244,12 @@
     private CTHdrFtr buildHdrFtr(String pStyle, XWPFParagraph[] paragraphs) {
         CTHdrFtr ftr = CTHdrFtr.Factory.newInstance();
         if (paragraphs != null) {
-            for (int i = 0 ; i < paragraphs.length ; i++) {
+            for (int i = 0; i < paragraphs.length; i++) {
                 CTP p = ftr.addNewP();
                 //ftr.setPArray(0, paragraphs[i].getCTP());		// MB 23 May 2010
-                ftr.setPArray(i, paragraphs[i].getCTP());   	// MB 23 May 2010
+                ftr.setPArray(i, paragraphs[i].getCTP());    // MB 23 May 2010
             }
-        }
-        else {
+        } else {
             CTP p = ftr.addNewP();
             byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();
             byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
@@ -270,21 +267,20 @@
      * and createFooter(int, XWPFParagraph[]) methods or the getXXXXXHeader/Footer methods where
      * headers or footers had been added to a document since it had been created/opened, returned
      * an object that contained no XWPFParagraph objects even if the header/footer itself did contain
-     * text. The reason was that this line of code; CTHdrFtr ftr = CTHdrFtr.Factory.newInstance(); 
+     * text. The reason was that this line of code; CTHdrFtr ftr = CTHdrFtr.Factory.newInstance();
      * created a brand new instance of the CTHDRFtr class which was then populated with data when
      * it should have recovered the CTHdrFtr object encapsulated within the XWPFHeaderFooter object
-     * that had previoulsy been instantiated in the createHeader(int, XWPFParagraph[]) or 
+     * that had previoulsy been instantiated in the createHeader(int, XWPFParagraph[]) or
      * createFooter(int, XWPFParagraph[]) methods.
      */
     private CTHdrFtr buildHdrFtr(String pStyle, XWPFParagraph[] paragraphs, XWPFHeaderFooter wrapper) {
         CTHdrFtr ftr = wrapper._getHdrFtr();
         if (paragraphs != null) {
-            for (int i = 0 ; i < paragraphs.length ; i++) {
+            for (int i = 0; i < paragraphs.length; i++) {
                 CTP p = ftr.addNewP();
                 ftr.setPArray(i, paragraphs[i].getCTP());
             }
-        }
-        else {
+        } else {
             CTP p = ftr.addNewP();
             byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();
             byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
@@ -330,60 +326,70 @@
     public XWPFHeader getFirstPageHeader() {
         return firstPageHeader;
     }
+
     public XWPFFooter getFirstPageFooter() {
         return firstPageFooter;
     }
+
     /**
      * Returns the odd page header. This is
-     *  also the same as the default one...
+     * also the same as the default one...
      */
     public XWPFHeader getOddPageHeader() {
         return defaultHeader;
     }
+
     /**
      * Returns the odd page footer. This is
-     *  also the same as the default one...
+     * also the same as the default one...
      */
     public XWPFFooter getOddPageFooter() {
         return defaultFooter;
     }
+
     public XWPFHeader getEvenPageHeader() {
         return evenPageHeader;
     }
+
     public XWPFFooter getEvenPageFooter() {
         return evenPageFooter;
     }
+
     public XWPFHeader getDefaultHeader() {
         return defaultHeader;
     }
+
     public XWPFFooter getDefaultFooter() {
         return defaultFooter;
     }
 
     /**
      * Get the header that applies to the given
-     *  (1 based) page.
+     * (1 based) page.
+     *
      * @param pageNumber The one based page number
      */
     public XWPFHeader getHeader(int pageNumber) {
-        if(pageNumber == 1 && firstPageHeader != null) {
+        if (pageNumber == 1 && firstPageHeader != null) {
             return firstPageHeader;
         }
-        if(pageNumber % 2 == 0 && evenPageHeader != null) {
+        if (pageNumber % 2 == 0 && evenPageHeader != null) {
             return evenPageHeader;
         }
         return defaultHeader;
     }
+
     /**
      * Get the footer that applies to the given
-     *  (1 based) page.
+     * (1 based) page.
+     *
      * @param pageNumber The one based page number
      */
     public XWPFFooter getFooter(int pageNumber) {
-        if(pageNumber == 1 && firstPageFooter != null) {
+        if (pageNumber == 1 && firstPageFooter != null) {
             return firstPageFooter;
         }
-        if(pageNumber % 2 == 0 && evenPageFooter != null) {
+        if (pageNumber % 2 == 0 && evenPageFooter != null) {
             return evenPageFooter;
         }
         return defaultFooter;
@@ -459,7 +465,7 @@
         lock.setExt(STExt.EDIT);
         CTShape shape = group.addNewShape();
         shape.setId("PowerPlusWaterMarkObject" + idx);
-        shape.setSpid("_x0000_s102" + (4+idx));
+        shape.setSpid("_x0000_s102" + (4 + idx));
         shape.setType("#_x0000_t136");
         shape.setStyle("position:absolute;margin-left:0;margin-top:0;width:415pt;height:207.5pt;z-index:-251654144;mso-wrap-edited:f;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin");
         shape.setWrapcoords("616 5068 390 16297 39 16921 -39 17155 7265 17545 7186 17467 -39 17467 18904 17467 10507 17467 8710 17545 18904 17077 18787 16843 18358 16297 18279 12554 19178 12476 20701 11774 20779 11228 21131 10059 21248 8811 21248 7563 20975 6316 20935 5380 19490 5146 14022 5068 2616 5068");
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHyperlinkDecorator.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHyperlinkDecorator.java
index d812034..27e8282 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHyperlinkDecorator.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHyperlinkDecorator.java
@@ -23,50 +23,49 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
 
 /**
- * Decorator class for XWPFParagraph allowing to add hyperlinks 
- *  found in paragraph to its text.
- *  
+ * Decorator class for XWPFParagraph allowing to add hyperlinks
+ * found in paragraph to its text.
+ * <p/>
  * Note - adds the hyperlink at the end, not in the right place...
- *  
+ *
  * @deprecated Use {@link XWPFHyperlinkRun} instead
  */
 @Deprecated
 public class XWPFHyperlinkDecorator extends XWPFParagraphDecorator {
-	private StringBuffer hyperlinkText;
-	
-	/**
-	 * @param nextDecorator The next decorator to use
-	 * @param outputHyperlinkUrls Should we output the links too, or just the link text?
-	 */
-	public XWPFHyperlinkDecorator(XWPFParagraphDecorator nextDecorator, boolean outputHyperlinkUrls) {
-		this(nextDecorator.paragraph, nextDecorator, outputHyperlinkUrls);
-	}
-	
-	/**
-	 * @param prgrph The paragraph of text to work on
-	 * @param outputHyperlinkUrls Should we output the links too, or just the link text?
-	 */
-	public XWPFHyperlinkDecorator(XWPFParagraph prgrph, XWPFParagraphDecorator nextDecorator, boolean outputHyperlinkUrls) {
-		super(prgrph, nextDecorator);
-		
-		hyperlinkText = new StringBuffer();
-		
-		// loop over hyperlink anchors
-		for(CTHyperlink link : paragraph.getCTP().getHyperlinkArray()){
-			for (CTR r : link.getRArray()) {
-				// Loop over text runs
-				for (CTText text : r.getTArray()){
-					hyperlinkText.append(text.getStringValue());
-				}
-			}
-			if(outputHyperlinkUrls && paragraph.getDocument().getHyperlinkByID(link.getId()) != null) {
-				hyperlinkText.append(" <"+paragraph.getDocument().getHyperlinkByID(link.getId()).getURL()+">");
-			}
-		}
-	}
-	
-	public String getText()
-	{
-		return super.getText() + hyperlinkText;
-	}
+    private StringBuffer hyperlinkText;
+
+    /**
+     * @param nextDecorator       The next decorator to use
+     * @param outputHyperlinkUrls Should we output the links too, or just the link text?
+     */
+    public XWPFHyperlinkDecorator(XWPFParagraphDecorator nextDecorator, boolean outputHyperlinkUrls) {
+        this(nextDecorator.paragraph, nextDecorator, outputHyperlinkUrls);
+    }
+
+    /**
+     * @param prgrph              The paragraph of text to work on
+     * @param outputHyperlinkUrls Should we output the links too, or just the link text?
+     */
+    public XWPFHyperlinkDecorator(XWPFParagraph prgrph, XWPFParagraphDecorator nextDecorator, boolean outputHyperlinkUrls) {
+        super(prgrph, nextDecorator);
+
+        hyperlinkText = new StringBuffer();
+
+        // loop over hyperlink anchors
+        for (CTHyperlink link : paragraph.getCTP().getHyperlinkArray()) {
+            for (CTR r : link.getRArray()) {
+                // Loop over text runs
+                for (CTText text : r.getTArray()) {
+                    hyperlinkText.append(text.getStringValue());
+                }
+            }
+            if (outputHyperlinkUrls && paragraph.getDocument().getHyperlinkByID(link.getId()) != null) {
+                hyperlinkText.append(" <" + paragraph.getDocument().getHyperlinkByID(link.getId()).getURL() + ">");
+            }
+        }
+    }
+
+    public String getText() {
+        return super.getText() + hyperlinkText;
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java
index 3946b22..46636c3 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFParagraphDecorator.java
@@ -22,22 +22,22 @@
  * Base decorator class for XWPFParagraph
  */
 public abstract class XWPFParagraphDecorator {
-	protected XWPFParagraph paragraph;
-	protected XWPFParagraphDecorator nextDecorator;
-	
-	public XWPFParagraphDecorator(XWPFParagraph paragraph) {
-		this(paragraph, null);
-	}
-	
-	public XWPFParagraphDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) {
-		this.paragraph = paragraph;
-		this.nextDecorator = nextDecorator;
-	}
-	
-	public String getText() {
-		if(nextDecorator != null) {
-			return nextDecorator.getText();
-		}
-		return paragraph.getText();
-	}
+    protected XWPFParagraph paragraph;
+    protected XWPFParagraphDecorator nextDecorator;
+
+    public XWPFParagraphDecorator(XWPFParagraph paragraph) {
+        this(paragraph, null);
+    }
+
+    public XWPFParagraphDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) {
+        this.paragraph = paragraph;
+        this.nextDecorator = nextDecorator;
+    }
+
+    public String getText() {
+        if (nextDecorator != null) {
+            return nextDecorator.getText();
+        }
+        return paragraph.getText();
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/package.html b/src/ooxml/java/org/apache/poi/xwpf/package.html
index 8c6c70d..0a59556 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/package.html
+++ b/src/ooxml/java/org/apache/poi/xwpf/package.html
@@ -19,9 +19,9 @@
 -->
 <html>
 <body>
-    <p>This package contains classes for handling Microsoft .docx
-       Word Processing files, known in POI as XWPF (XML Word Processing
-       Format).
-    </p>
+<p>This package contains classes for handling Microsoft .docx
+    Word Processing files, known in POI as XWPF (XML Word Processing
+    Format).
+</p>
 </body>
 </html>
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java
index e69b024..0e27546 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java
@@ -13,102 +13,92 @@
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
-==================================================================== */
-package org.apache.poi.xwpf.usermodel;
-
-import java.util.List;
-
-import org.apache.poi.POIXMLDocumentPart;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtPr;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
-
-/**
- * Experimental abstract class that is a base for XWPFSDT and XWPFSDTCell
- *  
- * WARNING - APIs expected to change rapidly.
- * 
- * These classes have so far been built only for read-only processing.
- * 
- */
-public abstract class AbstractXWPFSDT implements ISDTContents {
-   private final String title;
-   private final String tag;
-   private final IBody part;
-
-   @SuppressWarnings("deprecation")
-   public AbstractXWPFSDT(CTSdtPr pr, IBody part){
-       
-       CTString[] aliases = pr.getAliasArray();
-       if (aliases != null && aliases.length > 0){
-          title = aliases[0].getVal();
-       } else {
-          title = "";
-       }
-       CTString[] tags = pr.getTagArray();
-       if (tags != null && tags.length > 0){
-          tag = tags[0].getVal();
-       } else {
-          tag = "";
-       }
-       this.part = part;
-       
-   }
-
-   /**
-    * 
-    * @return first SDT Title
-    */
-   public String getTitle(){
-      return title;
-   }
-   
-   /**
-    * 
-    * @return first SDT Tag
-    */
-   public String getTag(){
-      return tag;
-   }
-   
-   /**
-    * 
-    * @return the content object
-    */
-   public abstract ISDTContent getContent();
-
-   /**
-    * 
-    * @return null
-    */
-   public IBody getBody() {
-      return null;
-   }
-
-   /**
-    * 
-    * @return document part
-    */
-   public POIXMLDocumentPart getPart() {
-      return part.getPart();
-   }
-
-   /**
-    * 
-    * @return partType
-    */
-   public BodyType getPartType() {
-      return BodyType.CONTENTCONTROL;
-   }
-
-   /**
-    * 
-    * @return element type
-    */
-   public BodyElementType getElementType() {
-      return BodyElementType.CONTENTCONTROL;
-   }
-
-   public XWPFDocument getDocument() {
-      return part.getXWPFDocument();
-   }
-}
+==================================================================== */

+package org.apache.poi.xwpf.usermodel;

+

+import org.apache.poi.POIXMLDocumentPart;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtPr;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;

+

+/**

+ * Experimental abstract class that is a base for XWPFSDT and XWPFSDTCell

+ * <p/>

+ * WARNING - APIs expected to change rapidly.

+ * <p/>

+ * These classes have so far been built only for read-only processing.

+ */

+public abstract class AbstractXWPFSDT implements ISDTContents {

+    private final String title;

+    private final String tag;

+    private final IBody part;

+

+    @SuppressWarnings("deprecation")

+    public AbstractXWPFSDT(CTSdtPr pr, IBody part) {

+

+        CTString[] aliases = pr.getAliasArray();

+        if (aliases != null && aliases.length > 0) {

+            title = aliases[0].getVal();

+        } else {

+            title = "";

+        }

+        CTString[] tags = pr.getTagArray();

+        if (tags != null && tags.length > 0) {

+            tag = tags[0].getVal();

+        } else {

+            tag = "";

+        }

+        this.part = part;

+

+    }

+

+    /**

+     * @return first SDT Title

+     */

+    public String getTitle() {

+        return title;

+    }

+

+    /**

+     * @return first SDT Tag

+     */

+    public String getTag() {

+        return tag;

+    }

+

+    /**

+     * @return the content object

+     */

+    public abstract ISDTContent getContent();

+

+    /**

+     * @return null

+     */

+    public IBody getBody() {

+        return null;

+    }

+

+    /**

+     * @return document part

+     */

+    public POIXMLDocumentPart getPart() {

+        return part.getPart();

+    }

+

+    /**

+     * @return partType

+     */

+    public BodyType getPartType() {

+        return BodyType.CONTENTCONTROL;

+    }

+

+    /**

+     * @return element type

+     */

+    public BodyElementType getElementType() {

+        return BodyElementType.CONTENTCONTROL;

+    }

+

+    public XWPFDocument getDocument() {

+        return part.getXWPFDocument();

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
index 160c637..5a1df0e 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
@@ -21,15 +21,14 @@
  * <p>
  * 9 Jan 2010
  * </p>
- * <p>
- * // TODO insert Javadoc here!
- * </p>
- * @author epp
- *
- */
-public enum BodyElementType {
-   CONTENTCONTROL,
-   PARAGRAPH,
-	TABLE,
-	
-}
+ * <p>

+ * // TODO insert Javadoc here!

+ * </p>

+ *

+ * @author epp

+ */

+public enum BodyElementType {

+    CONTENTCONTROL,

+    PARAGRAPH,

+    TABLE,

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java
index 48ea33d..b7937e5 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java
@@ -29,14 +29,15 @@
  * </li>
  * <li> Art borders: which specify a repeated image to be used
  * when drawing a border around the specified object. Line borders may be
- * specified on any object which allows a border, however, art borders may only
- * be used as a border at the page level - the borders under the pgBorders
- * element
- *</li>
- * </ul>
- * @author Gisella Bronzetti
- */
-public enum Borders {
+ * specified on any object which allows a border, however, art borders may only

+ * be used as a border at the page level - the borders under the pgBorders

+ * element

+ * </li>

+ * </ul>

+ *

+ * @author Gisella Bronzetti

+ */

+public enum Borders {

 
     NIL(1),
 
@@ -596,31 +597,32 @@
     ZANY_TRIANGLES(189),
 
     ZIG_ZAG(190),
-
-    ZIG_ZAG_STITCH(191);
-
-    private final int value;
-
-    private Borders(int val) {
-        value = val;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    private static Map<Integer, Borders> imap = new HashMap<Integer, Borders>();
-    static {
-        for (Borders p : values()) {
-            imap.put(Integer.valueOf(p.getValue()), p);
-        }
-    }
-
-    public static Borders valueOf(int type) {
-        Borders pBorder = imap.get(Integer.valueOf(type));
-        if (pBorder == null) {
-            throw new IllegalArgumentException("Unknown paragraph border: " + type);
-        }
-        return pBorder;
-    }
-}
+

+    ZIG_ZAG_STITCH(191);

+

+    private static Map<Integer, Borders> imap = new HashMap<Integer, Borders>();

+

+    static {

+        for (Borders p : values()) {

+            imap.put(Integer.valueOf(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private Borders(int val) {

+        value = val;

+    }

+

+    public static Borders valueOf(int type) {

+        Borders pBorder = imap.get(Integer.valueOf(type));

+        if (pBorder == null) {

+            throw new IllegalArgumentException("Unknown paragraph border: " + type);

+        }

+        return pBorder;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java
index 8ad9890..4fbef1d 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakClear.java
@@ -20,23 +20,23 @@
 import java.util.Map;
 
 /**
- * Specifies the set of possible restart locations which may be used as to
- * determine the next available line when a break's type attribute has a value
- * of textWrapping.
- * 
- * @author Gisella Bronzetti
- */
-public enum BreakClear {
+ * Specifies the set of possible restart locations which may be used as to

+ * determine the next available line when a break's type attribute has a value

+ * of textWrapping.

+ *

+ * @author Gisella Bronzetti

+ */

+public enum BreakClear {

 
     /**
      * Specifies that the text wrapping break shall advance the text to the next
-     * line in the WordprocessingML document, regardless of its position left to
-     * right or the presence of any floating objects which intersect with the
-     * line,
-     * 
-     * This is the setting for a typical line break in a document.
-     */
-
+     * line in the WordprocessingML document, regardless of its position left to

+     * right or the presence of any floating objects which intersect with the

+     * line,

+     * <p/>

+     * This is the setting for a typical line break in a document.

+     */

+

     NONE(1),
 
     /**
@@ -80,31 +80,32 @@
      * Specifies that the text wrapping break shall advance the text to the next
      * line in the WordprocessingML document which spans the full width of the
      * line.
-     */
-    ALL(4);
-
-    private final int value;
-
-    private BreakClear(int val) {
-       value = val;
-    }
-
-    public int getValue() {
-       return value;
-    }
-
-    private static Map<Integer, BreakClear> imap = new HashMap<Integer, BreakClear>();
-    static {
-       for (BreakClear p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static BreakClear valueOf(int type) {
-       BreakClear bType = imap.get(new Integer(type));
-       if (bType == null)
-          throw new IllegalArgumentException("Unknown break clear type: "
-                + type);
-       return bType;
-    }
-}
+     */

+    ALL(4);

+

+    private static Map<Integer, BreakClear> imap = new HashMap<Integer, BreakClear>();

+

+    static {

+        for (BreakClear p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private BreakClear(int val) {

+        value = val;

+    }

+

+    public static BreakClear valueOf(int type) {

+        BreakClear bType = imap.get(new Integer(type));

+        if (bType == null)

+            throw new IllegalArgumentException("Unknown break clear type: "

+                    + type);

+        return bType;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java
index 60b3522..94cddab 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BreakType.java
@@ -21,18 +21,18 @@
 
 /**
  * Specifies the possible types of break characters in a WordprocessingML
- * document.
- * The break type determines the next location where text shall be
- * placed after this manual break is applied to the text contents
- * 
- * @author Gisella Bronzetti
- */
-public enum BreakType {
-
-    
-    /**
-     * Specifies that the current break shall restart itself on the next page of
-     * the document when the document is displayed in page view.
+ * document.

+ * The break type determines the next location where text shall be

+ * placed after this manual break is applied to the text contents

+ *

+ * @author Gisella Bronzetti

+ */

+public enum BreakType {

+

+

+    /**

+     * Specifies that the current break shall restart itself on the next page of

+     * the document when the document is displayed in page view.

      */
     PAGE(1),
 
@@ -53,31 +53,32 @@
      * the document when the document is displayed in page view.
      * The determine of the next line shall be done subject to the value of the clear
      * attribute on the specified break character.
-     */
-    TEXT_WRAPPING(3);
-
-    private final int value;
-
-    private BreakType(int val) {
-       value = val;
-    }
-
-    public int getValue() {
-       return value;
-    }
-
-    private static Map<Integer, BreakType> imap = new HashMap<Integer, BreakType>();
-    static {
-       for (BreakType p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static BreakType valueOf(int type) {
-       BreakType bType = imap.get(new Integer(type));
-       if (bType == null)
-          throw new IllegalArgumentException("Unknown break type: "
-                + type);
-       return bType;
-    }
-}
+     */

+    TEXT_WRAPPING(3);

+

+    private static Map<Integer, BreakType> imap = new HashMap<Integer, BreakType>();

+

+    static {

+        for (BreakType p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private BreakType(int val) {

+        value = val;

+    }

+

+    public static BreakType valueOf(int type) {

+        BreakType bType = imap.get(new Integer(type));

+        if (bType == null)

+            throw new IllegalArgumentException("Unknown break type: "

+                    + type);

+        return bType;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
index 2df6f57..077697a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
@@ -14,31 +14,45 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-package org.apache.poi.xwpf.usermodel;
-
-public interface Document {
-    /** Extended windows meta file */
-    public static final int PICTURE_TYPE_EMF = 2;
-
-    /** Windows Meta File */
-    public static final int PICTURE_TYPE_WMF = 3;
-
-    /** Mac PICT format */
-    public static final int PICTURE_TYPE_PICT = 4;
-
-    /** JPEG format */
-    public static final int PICTURE_TYPE_JPEG = 5;
-
-    /** PNG format */
-    public static final int PICTURE_TYPE_PNG = 6;
-
-    /** Device independent bitmap */
-    public static final int PICTURE_TYPE_DIB = 7;
-
-    /** GIF image format */
-    public static final int PICTURE_TYPE_GIF = 8;
-
-    /**
+package org.apache.poi.xwpf.usermodel;

+

+public interface Document {

+    /**

+     * Extended windows meta file

+     */

+    public static final int PICTURE_TYPE_EMF = 2;

+

+    /**

+     * Windows Meta File

+     */

+    public static final int PICTURE_TYPE_WMF = 3;

+

+    /**

+     * Mac PICT format

+     */

+    public static final int PICTURE_TYPE_PICT = 4;

+

+    /**

+     * JPEG format

+     */

+    public static final int PICTURE_TYPE_JPEG = 5;

+

+    /**

+     * PNG format

+     */

+    public static final int PICTURE_TYPE_PNG = 6;

+

+    /**

+     * Device independent bitmap

+     */

+    public static final int PICTURE_TYPE_DIB = 7;

+

+    /**

+     * GIF image format

+     */

+    public static final int PICTURE_TYPE_GIF = 8;

+

+    /**

      * Tag Image File (.tiff)
      */
     public static final int PICTURE_TYPE_TIFF = 9;
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
index e035888..6e9ce05 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
@@ -27,64 +27,68 @@
 
 /**
  * <p>An IBody represents the different parts of the document which
- * can contain collections of Paragraphs and Tables. It provides a
- * common way to work with these and their contents.</p>
- * <p>Typically, this is something like a XWPFDocument, or one of
- *  the parts in it like XWPFHeader, XWPFFooter, XWPFTableCell
- * </p>
- */
-public interface IBody {
+ * can contain collections of Paragraphs and Tables. It provides a

+ * common way to work with these and their contents.</p>

+ * <p>Typically, this is something like a XWPFDocument, or one of

+ * the parts in it like XWPFHeader, XWPFFooter, XWPFTableCell

+ * </p>

+ */

+public interface IBody {

     /**
-     * returns the Part, to which the body belongs, which you need for adding relationship to other parts
-     * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
-     * belongs.
-     * @return the Part, to which the body belongs
-     */
-    public POIXMLDocumentPart getPart();
-
-    /**
-     * get the PartType of the body, for example
-     * DOCUMENT, HEADER, FOOTER, FOOTNOTE, 
-     * @return the PartType of the body
-     */
-    public BodyType getPartType();
-
-    /**
-     * Returns an Iterator with paragraphs and tables, 
-     *  in the order that they occur in the text.
-     */
-    public List<IBodyElement> getBodyElements();
-
-    /**
-     * Returns the paragraph(s) that holds
-     *  the text of the header or footer.
-     */
-    public List<XWPFParagraph> getParagraphs();
-
-    /**
-     * Return the table(s) that holds the text
-     *  of the IBodyPart, for complex cases
-     *  where a paragraph isn't used.
-     */
-    public List<XWPFTable> getTables();
-
-    /**
-     * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer
-     * the method will return this paragraph
-     * if there is no corresponding {@link XWPFParagraph} the method will return null 
-     * @param p is instance of CTP and is searching for an XWPFParagraph
-     * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer
-     * 		   XWPFParagraph with the correspondig CTP p
-     */
-    public XWPFParagraph getParagraph(CTP p);
-
-    /**
-     * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header
-     * the method will return this table
-     * if there is no corresponding {@link XWPFTable} the method will return null 
-     * @param ctTable
-     */
-    public XWPFTable getTable(CTTbl ctTable);
+     * returns the Part, to which the body belongs, which you need for adding relationship to other parts

+     * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell

+     * belongs.

+     *

+     * @return the Part, to which the body belongs

+     */

+    public POIXMLDocumentPart getPart();

+

+    /**

+     * get the PartType of the body, for example

+     * DOCUMENT, HEADER, FOOTER, FOOTNOTE,

+     *

+     * @return the PartType of the body

+     */

+    public BodyType getPartType();

+

+    /**

+     * Returns an Iterator with paragraphs and tables,

+     * in the order that they occur in the text.

+     */

+    public List<IBodyElement> getBodyElements();

+

+    /**

+     * Returns the paragraph(s) that holds

+     * the text of the header or footer.

+     */

+    public List<XWPFParagraph> getParagraphs();

+

+    /**

+     * Return the table(s) that holds the text

+     * of the IBodyPart, for complex cases

+     * where a paragraph isn't used.

+     */

+    public List<XWPFTable> getTables();

+

+    /**

+     * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer

+     * the method will return this paragraph

+     * if there is no corresponding {@link XWPFParagraph} the method will return null

+     *

+     * @param p is instance of CTP and is searching for an XWPFParagraph

+     * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer

+     * XWPFParagraph with the correspondig CTP p

+     */

+    public XWPFParagraph getParagraph(CTP p);

+

+    /**

+     * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header

+     * the method will return this table

+     * if there is no corresponding {@link XWPFTable} the method will return null

+     *

+     * @param ctTable

+     */

+    public XWPFTable getTable(CTTbl ctTable);

 
     /**
      * Returns the paragraph that of position pos
@@ -94,32 +98,36 @@
     /**
      * Returns the table at position pos
      */
-    public XWPFTable getTableArray(int pos);
-
-    /**
-     *inserts a new paragraph at position of the cursor
-     * @param cursor
-     */
-    public XWPFParagraph insertNewParagraph(XmlCursor cursor);
-
-    /**
-     * inserts a new Table at the cursor position.
-     * @param cursor
-     */
-    public XWPFTable insertNewTbl(XmlCursor cursor);
-
-    /**
-     * inserts a new Table at position pos
-     * @param pos
-     * @param table
-     */
+    public XWPFTable getTableArray(int pos);

+

+    /**

+     * inserts a new paragraph at position of the cursor

+     *

+     * @param cursor

+     */

+    public XWPFParagraph insertNewParagraph(XmlCursor cursor);

+

+    /**

+     * inserts a new Table at the cursor position.

+     *

+     * @param cursor

+     */

+    public XWPFTable insertNewTbl(XmlCursor cursor);

+

+    /**

+     * inserts a new Table at position pos

+     *

+     * @param pos

+     * @param table

+     */

     void insertTable(int pos, XWPFTable table);
-
-    /**
-     * returns the TableCell to which the Table belongs
-     * @param cell
-     */
-    public XWPFTableCell getTableCell(CTTc cell);
+

+    /**

+     * returns the TableCell to which the Table belongs

+     *

+     * @param cell

+     */

+    public XWPFTableCell getTableCell(CTTc cell);

 
     /**
      * Return XWPFDocument
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
index 70009be..312ea49 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
@@ -18,15 +18,18 @@
 package org.apache.poi.xwpf.usermodel;
 
 import org.apache.poi.POIXMLDocumentPart;
-
-/**
- * 9 Jan 2010
- * @author Philipp Epp
- *
- */
-public interface IBodyElement{
-	IBody getBody();
-    POIXMLDocumentPart getPart();
-	BodyType getPartType();
-	BodyElementType getElementType();
-}
+

+/**

+ * 9 Jan 2010

+ *

+ * @author Philipp Epp

+ */

+public interface IBodyElement {

+    IBody getBody();

+

+    POIXMLDocumentPart getPart();

+

+    BodyType getPartType();

+

+    BodyElementType getElementType();

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java
index cf32924..0ac12c7 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ICell.java
@@ -15,13 +15,13 @@
    limitations under the License.
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
-
-/**
- * Interface for anything that can be at a table cell level:
- *  {@link XWPFTableCell}, {@link XWPFSDTCell}
- *  <p>
- *  Schematically something like this:
- *  &lt;tr&gt;&lt;tc/&gt;&lt;tc/&gt;&lt;sdt&gt&lt;tc/&gt;&lt;/sdt&gt;&lt;/tr&gt;
- */
-public interface ICell {
-}
+

+/**

+ * Interface for anything that can be at a table cell level:

+ * {@link XWPFTableCell}, {@link XWPFSDTCell}

+ * <p/>

+ * Schematically something like this:

+ * &lt;tr&gt;&lt;tc/&gt;&lt;tc/&gt;&lt;sdt&gt&lt;tc/&gt;&lt;/sdt&gt;&lt;/tr&gt;

+ */

+public interface ICell {

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java
index 3ea4aca..fea7856 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunBody.java
@@ -22,10 +22,11 @@
 /**
  * Simple interface describing both {@link XWPFParagraph}
  * and {@link XWPFSDT}
- * 
+ * <p/>
  * TODO Should this be based on / extend {@link Paragraph}?
  */
 public interface IRunBody {
-   public XWPFDocument getDocument();
-   public POIXMLDocumentPart getPart();
+    public XWPFDocument getDocument();
+
+    public POIXMLDocumentPart getPart();
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java
index f11b46a..e8d1b83 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IRunElement.java
@@ -20,11 +20,10 @@
 
 /**
  * Common interface for things that can occur
- *  where a run (text with common stylings) can,
- *  eg {@link XWPFRun} or {@link XWPFSDT}.
+ * where a run (text with common stylings) can,
+ * eg {@link XWPFRun} or {@link XWPFSDT}.
  * TODO More methods to follow shortly!
- * 
+ * <p/>
  * TODO Make this based on {@link CharacterRun}
  */
-public interface IRunElement {
-}
\ No newline at end of file
+public interface IRunElement {}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java
index 25599d7..5493ff3 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContent.java
@@ -15,21 +15,20 @@
    limitations under the License.
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
-
-
-/**
- * Experimental interface to offer rudimentary read-only processing of 
- *  of the contentblock of an SDT/ContentControl.
- *  
- *
- *
- * WARNING - APIs expected to change rapidly
- * 
- */
-public interface ISDTContent  {
-
-    public String getText();
-
-    public String toString();
-    
+

+

+/**

+ * Experimental interface to offer rudimentary read-only processing of

+ * of the contentblock of an SDT/ContentControl.

+ * <p/>

+ * <p/>

+ * <p/>

+ * WARNING - APIs expected to change rapidly

+ */

+public interface ISDTContent {

+

+    public String getText();

+

+    public String toString();

+

 }

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java
index 40776e2..66922b8 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ISDTContents.java
@@ -18,8 +18,8 @@
 
 /**
  * Interface for anything that can be within an SDT:
- *  {@link XWPFRun}, {@link XWPFTable}, {@link XWPFParagraph},
- *  {@link XWPFSDT} etc
+ * {@link XWPFRun}, {@link XWPFTable}, {@link XWPFParagraph},
+ * {@link XWPFSDT} etc
  */
 public interface ISDTContents {
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java
index 166d8e7..b46c532 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/LineSpacingRule.java
@@ -19,13 +19,13 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/**
- * Specifies the logic which shall be used to calculate the line spacing of the
- * parent object when it is displayed in the document.
- * 
- * @author Gisella Bronzetti
- */
-public enum LineSpacingRule {
+/**

+ * Specifies the logic which shall be used to calculate the line spacing of the

+ * parent object when it is displayed in the document.

+ *

+ * @author Gisella Bronzetti

+ */

+public enum LineSpacingRule {

 
     /**
      * Specifies that the line spacing of the parent object shall be
@@ -45,31 +45,32 @@
     /**
      * Specifies that the height of the line shall be at least the value
      * specified, but may be expanded to fit its content as needed.
-     */
-    AT_LEAST(3);
-
-    
-    private final int value;
-
-    private LineSpacingRule(int val) {
-       value = val;
-    }
-
-    public int getValue() {
-       return value;
-    }
-
-    private static Map<Integer, LineSpacingRule> imap = new HashMap<Integer, LineSpacingRule>();
-    static {
-       for (LineSpacingRule p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static LineSpacingRule valueOf(int type) {
-       LineSpacingRule lineType = imap.get(new Integer(type));
-       if (lineType == null)
-          throw new IllegalArgumentException("Unknown line type: " + type);
-       return lineType;
-    }
-}
+     */

+    AT_LEAST(3);

+

+

+    private static Map<Integer, LineSpacingRule> imap = new HashMap<Integer, LineSpacingRule>();

+

+    static {

+        for (LineSpacingRule p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private LineSpacingRule(int val) {

+        value = val;

+    }

+

+    public static LineSpacingRule valueOf(int type) {

+        LineSpacingRule lineType = imap.get(new Integer(type));

+        if (lineType == null)

+            throw new IllegalArgumentException("Unknown line type: " + type);

+        return lineType;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
index 0585ecb..226d409 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
@@ -37,30 +37,31 @@
     DISTRIBUTE(6),
     NUM_TAB(7),
     HIGH_KASHIDA(8),
-    LOW_KASHIDA(9),
-    THAI_DISTRIBUTE(10);
-
-    private final int value;
-
-    private ParagraphAlignment(int val){
-        value = val;
-    }
-
-    public int getValue(){
-        return value;
-    }
-
-    private static Map<Integer, ParagraphAlignment> imap = new HashMap<Integer, ParagraphAlignment>();
-    static{
-        for (ParagraphAlignment p : values()) {
-            imap.put(new Integer(p.getValue()), p);
-        }
-    }
-
-    public static ParagraphAlignment valueOf(int type){
-        ParagraphAlignment err = imap.get(new Integer(type));
-        if(err == null) throw new IllegalArgumentException("Unknown paragraph alignment: " + type);
-        return err;
-    }
-
-}
+    LOW_KASHIDA(9),

+    THAI_DISTRIBUTE(10);

+

+    private static Map<Integer, ParagraphAlignment> imap = new HashMap<Integer, ParagraphAlignment>();

+

+    static {

+        for (ParagraphAlignment p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private ParagraphAlignment(int val) {

+        value = val;

+    }

+

+    public static ParagraphAlignment valueOf(int type) {

+        ParagraphAlignment err = imap.get(new Integer(type));

+        if (err == null) throw new IllegalArgumentException("Unknown paragraph alignment: " + type);

+        return err;

+    }

+

+    public int getValue() {

+        return value;

+    }

+

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
index 5e387e7..4eebe41 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
@@ -17,49 +17,47 @@
 
 package org.apache.poi.xwpf.usermodel;
 
-
-/**
- * postion of a character in a paragrapho
-* 1st RunPositon
-* 2nd TextPosition
-* 3rd CharacterPosition 
-* 
-*
-*/
-public class PositionInParagraph {
-	private int posRun = 0, posText = 0, posChar = 0;
-
-	public PositionInParagraph(){
-	}
-	
-	public PositionInParagraph(int posRun, int posText, int posChar){
-		this.posRun=posRun;
-		this.posChar=posChar;
-		this.posText= posText;
-	}
-	
-	public int getRun() {
-		return posRun;
-	}
-
-	public void setRun(int beginRun) {
-		this.posRun = beginRun;
-	}
-
-	public int getText() {
-		return posText;
-	}
-
-	public void setText(int beginText) {
-		this.posText = beginText;
-	}
-
-	public int getChar() {
-		return posChar;
-	}
-
-	public void setChar(int beginChar) {
-		this.posChar = beginChar;
-	}
-
-}
+

+/**

+ * postion of a character in a paragrapho

+ * 1st RunPositon

+ * 2nd TextPosition

+ * 3rd CharacterPosition

+ */

+public class PositionInParagraph {

+    private int posRun = 0, posText = 0, posChar = 0;

+

+    public PositionInParagraph() {

+    }

+

+    public PositionInParagraph(int posRun, int posText, int posChar) {

+        this.posRun = posRun;

+        this.posChar = posChar;

+        this.posText = posText;

+    }

+

+    public int getRun() {

+        return posRun;

+    }

+

+    public void setRun(int beginRun) {

+        this.posRun = beginRun;

+    }

+

+    public int getText() {

+        return posText;

+    }

+

+    public void setText(int beginText) {

+        this.posText = beginText;

+    }

+

+    public int getChar() {

+        return posChar;

+    }

+

+    public void setChar(int beginChar) {

+        this.posChar = beginChar;

+    }

+

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
index f144e62..b7dc6ee 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
@@ -38,85 +38,85 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabTlc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTheme;
-
-public class TOC {
-
-	CTSdtBlock block;
-
-	public TOC() {
-		this(CTSdtBlock.Factory.newInstance());
-	}
-
-	public TOC(CTSdtBlock block) {
-		this.block = block;
-		CTSdtPr sdtPr = block.addNewSdtPr();
-		CTDecimalNumber id = sdtPr.addNewId();
-		id.setVal(new BigInteger("4844945"));
-		sdtPr.addNewDocPartObj().addNewDocPartGallery().setVal("Table of contents");
-		CTSdtEndPr sdtEndPr = block.addNewSdtEndPr();
-		CTRPr rPr = sdtEndPr.addNewRPr();
-		CTFonts fonts = rPr.addNewRFonts();
-		fonts.setAsciiTheme(STTheme.MINOR_H_ANSI);
-		fonts.setEastAsiaTheme(STTheme.MINOR_H_ANSI);
-		fonts.setHAnsiTheme(STTheme.MINOR_H_ANSI);
-		fonts.setCstheme(STTheme.MINOR_BIDI);
-		rPr.addNewB().setVal(STOnOff.OFF);
-		rPr.addNewBCs().setVal(STOnOff.OFF);
-		rPr.addNewColor().setVal("auto");
-		rPr.addNewSz().setVal(new BigInteger("24"));
-		rPr.addNewSzCs().setVal(new BigInteger("24"));
-		CTSdtContentBlock content = block.addNewSdtContent();
-		CTP p = content.addNewP();
-		p.setRsidR("00EF7E24".getBytes());
-		p.setRsidRDefault("00EF7E24".getBytes());
-		p.addNewPPr().addNewPStyle().setVal("TOCHeading");
-		p.addNewR().addNewT().setStringValue("Table of Contents");
-	}
-
-    @Internal
-    public CTSdtBlock getBlock() {
-		return this.block;
-	}
-
-	public void addRow(int level, String title, int page, String bookmarkRef) {
-		CTSdtContentBlock contentBlock = this.block.getSdtContent();
-		CTP p = contentBlock.addNewP();
-		p.setRsidR("00EF7E24".getBytes());
-		p.setRsidRDefault("00EF7E24".getBytes());
-		CTPPr pPr = p.addNewPPr();
-		pPr.addNewPStyle().setVal("TOC" + level);
-		CTTabs tabs = pPr.addNewTabs();
-		CTTabStop tab = tabs.addNewTab();
-		tab.setVal(STTabJc.RIGHT);
-		tab.setLeader(STTabTlc.DOT);
-		tab.setPos(new BigInteger("8290"));
-		pPr.addNewRPr().addNewNoProof();
-		CTR run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewT().setStringValue(title);
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewTab();
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewFldChar().setFldCharType(STFldCharType.BEGIN);
-		// pageref run
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		CTText text = run.addNewInstrText();
-		text.setSpace(Space.PRESERVE);
-		// bookmark reference
-		text.setStringValue(" PAGEREF _Toc" + bookmarkRef + " \\h ");
-		p.addNewR().addNewRPr().addNewNoProof();
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
-		// page number run
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewT().setStringValue(Integer.valueOf(page).toString());
-		run = p.addNewR();
-		run.addNewRPr().addNewNoProof();
-		run.addNewFldChar().setFldCharType(STFldCharType.END);
-	}
-}
+

+public class TOC {

+

+    CTSdtBlock block;

+

+    public TOC() {

+        this(CTSdtBlock.Factory.newInstance());

+    }

+

+    public TOC(CTSdtBlock block) {

+        this.block = block;

+        CTSdtPr sdtPr = block.addNewSdtPr();

+        CTDecimalNumber id = sdtPr.addNewId();

+        id.setVal(new BigInteger("4844945"));

+        sdtPr.addNewDocPartObj().addNewDocPartGallery().setVal("Table of contents");

+        CTSdtEndPr sdtEndPr = block.addNewSdtEndPr();

+        CTRPr rPr = sdtEndPr.addNewRPr();

+        CTFonts fonts = rPr.addNewRFonts();

+        fonts.setAsciiTheme(STTheme.MINOR_H_ANSI);

+        fonts.setEastAsiaTheme(STTheme.MINOR_H_ANSI);

+        fonts.setHAnsiTheme(STTheme.MINOR_H_ANSI);

+        fonts.setCstheme(STTheme.MINOR_BIDI);

+        rPr.addNewB().setVal(STOnOff.OFF);

+        rPr.addNewBCs().setVal(STOnOff.OFF);

+        rPr.addNewColor().setVal("auto");

+        rPr.addNewSz().setVal(new BigInteger("24"));

+        rPr.addNewSzCs().setVal(new BigInteger("24"));

+        CTSdtContentBlock content = block.addNewSdtContent();

+        CTP p = content.addNewP();

+        p.setRsidR("00EF7E24".getBytes());

+        p.setRsidRDefault("00EF7E24".getBytes());

+        p.addNewPPr().addNewPStyle().setVal("TOCHeading");

+        p.addNewR().addNewT().setStringValue("Table of Contents");

+    }

+

+    @Internal

+    public CTSdtBlock getBlock() {

+        return this.block;

+    }

+

+    public void addRow(int level, String title, int page, String bookmarkRef) {

+        CTSdtContentBlock contentBlock = this.block.getSdtContent();

+        CTP p = contentBlock.addNewP();

+        p.setRsidR("00EF7E24".getBytes());

+        p.setRsidRDefault("00EF7E24".getBytes());

+        CTPPr pPr = p.addNewPPr();

+        pPr.addNewPStyle().setVal("TOC" + level);

+        CTTabs tabs = pPr.addNewTabs();

+        CTTabStop tab = tabs.addNewTab();

+        tab.setVal(STTabJc.RIGHT);

+        tab.setLeader(STTabTlc.DOT);

+        tab.setPos(new BigInteger("8290"));

+        pPr.addNewRPr().addNewNoProof();

+        CTR run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewT().setStringValue(title);

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewTab();

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewFldChar().setFldCharType(STFldCharType.BEGIN);

+        // pageref run

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        CTText text = run.addNewInstrText();

+        text.setSpace(Space.PRESERVE);

+        // bookmark reference

+        text.setStringValue(" PAGEREF _Toc" + bookmarkRef + " \\h ");

+        p.addNewR().addNewRPr().addNewNoProof();

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewFldChar().setFldCharType(STFldCharType.SEPARATE);

+        // page number run

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewT().setStringValue(Integer.valueOf(page).toString());

+        run = p.addNewR();

+        run.addNewRPr().addNewNoProof();

+        run.addNewFldChar().setFldCharType(STFldCharType.END);

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java
index b2a8c13..7c1187d 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextAlignment.java
@@ -17,25 +17,25 @@
 package org.apache.poi.xwpf.usermodel;
 
 import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Specifies all types of vertical alignment which are available to be applied to of all text 
- * on each line displayed within a paragraph.
- * 
- * @author Gisella Bronzetti
- */
-public enum TextAlignment {
-    /**
-     * Specifies that all text in the parent object shall be 
-     * aligned to the top of each character when displayed
-     */
-    TOP(1),
-    /**
-     * Specifies that all text in the parent object shall be 
-     * aligned to the center of each character when displayed.
-     */
-    CENTER(2),
+import java.util.Map;

+

+/**

+ * Specifies all types of vertical alignment which are available to be applied to of all text

+ * on each line displayed within a paragraph.

+ *

+ * @author Gisella Bronzetti

+ */

+public enum TextAlignment {

+    /**

+     * Specifies that all text in the parent object shall be

+     * aligned to the top of each character when displayed

+     */

+    TOP(1),

+    /**

+     * Specifies that all text in the parent object shall be

+     * aligned to the center of each character when displayed.

+     */

+    CENTER(2),

     /**
      * Specifies that all text in the parent object shall be
      * aligned to the baseline of each character when displayed.
@@ -44,34 +44,35 @@
     /**
      * Specifies that all text in the parent object shall be
      * aligned to the bottom of each character when displayed.
-     */
-    BOTTOM(4),
-    /**
-     * Specifies that all text in the parent object shall be 
-     * aligned automatically when displayed.
-     */
-    AUTO(5);
-
-    private final int value;
-
-    private TextAlignment(int val){
-	value = val;
-    }
-
-    public int getValue(){
-       return value;
-    }
-
-    private static Map<Integer, TextAlignment> imap = new HashMap<Integer, TextAlignment>();
-    static{
-       for (TextAlignment p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static TextAlignment valueOf(int type){
-       TextAlignment align = imap.get(new Integer(type));
-       if(align == null) throw new IllegalArgumentException("Unknown text alignment: " + type);
-       return align;
-    }
-}
+     */

+    BOTTOM(4),

+    /**

+     * Specifies that all text in the parent object shall be

+     * aligned automatically when displayed.

+     */

+    AUTO(5);

+

+    private static Map<Integer, TextAlignment> imap = new HashMap<Integer, TextAlignment>();

+

+    static {

+        for (TextAlignment p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private TextAlignment(int val) {

+        value = val;

+    }

+

+    public static TextAlignment valueOf(int type) {

+        TextAlignment align = imap.get(new Integer(type));

+        if (align == null) throw new IllegalArgumentException("Unknown text alignment: " + type);

+        return align;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
index 23aa158..44477da 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
@@ -16,83 +16,84 @@
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
-
-/**
- * saves the begin and end position  of a text in a Paragraph
-*/
-public class TextSegement {
-	private PositionInParagraph beginPos;
-	private PositionInParagraph endPos;
-
-	public TextSegement(){
-		this.beginPos = new PositionInParagraph();
-		this. endPos = new PositionInParagraph();		
-	}
-	
-	public TextSegement(int beginRun, int endRun, int beginText, int endText, int beginChar, int endChar){
-		PositionInParagraph beginPos = new PositionInParagraph(beginRun, beginText, beginChar);
-		PositionInParagraph endPos = new PositionInParagraph(endRun, endText, endChar);
-		this.beginPos = beginPos;
-		this.endPos = endPos;
-	}
-	
-	public TextSegement(PositionInParagraph beginPos, PositionInParagraph endPos){
-		this.beginPos = beginPos;
-		this.endPos = endPos;
-	}
-
-	public PositionInParagraph getBeginPos(){
-		return beginPos;
-	}
-	
-	public PositionInParagraph getEndPos(){
-		return endPos;
-	}
-	
-	public int getBeginRun(){
-		return beginPos.getRun();
-	}
-	
-	public void setBeginRun(int beginRun){
-		beginPos.setRun(beginRun);
-	}
-	
-	public int getBeginText(){
-		return beginPos.getText();
-	}
-	
-	public void setBeginText(int beginText){
-		beginPos.setText(beginText);
-	}
-	
-	public int getBeginChar(){
-		return beginPos.getChar();
-	}
-	
-	public void setBeginChar(int beginChar){
-		beginPos.setChar(beginChar);
-	}
-	public int getEndRun(){
-		return endPos.getRun();
-	}
-	
-	public void setEndRun(int endRun){
-		endPos.setRun(endRun);
-	}
-	
-	public int getEndText(){
-		return endPos.getText();
-	}
-	
-	public void setEndText(int endText){
-		endPos.setText(endText);
-	}
-	
-	public int getEndChar(){
-		return endPos.getChar();
-	}
-	
-	public void setEndChar(int endChar){
-		endPos.setChar(endChar);
-	}
-}
+

+/**

+ * saves the begin and end position  of a text in a Paragraph

+ */

+public class TextSegement {

+    private PositionInParagraph beginPos;

+    private PositionInParagraph endPos;

+

+    public TextSegement() {

+        this.beginPos = new PositionInParagraph();

+        this.endPos = new PositionInParagraph();

+    }

+

+    public TextSegement(int beginRun, int endRun, int beginText, int endText, int beginChar, int endChar) {

+        PositionInParagraph beginPos = new PositionInParagraph(beginRun, beginText, beginChar);

+        PositionInParagraph endPos = new PositionInParagraph(endRun, endText, endChar);

+        this.beginPos = beginPos;

+        this.endPos = endPos;

+    }

+

+    public TextSegement(PositionInParagraph beginPos, PositionInParagraph endPos) {

+        this.beginPos = beginPos;

+        this.endPos = endPos;

+    }

+

+    public PositionInParagraph getBeginPos() {

+        return beginPos;

+    }

+

+    public PositionInParagraph getEndPos() {

+        return endPos;

+    }

+

+    public int getBeginRun() {

+        return beginPos.getRun();

+    }

+

+    public void setBeginRun(int beginRun) {

+        beginPos.setRun(beginRun);

+    }

+

+    public int getBeginText() {

+        return beginPos.getText();

+    }

+

+    public void setBeginText(int beginText) {

+        beginPos.setText(beginText);

+    }

+

+    public int getBeginChar() {

+        return beginPos.getChar();

+    }

+

+    public void setBeginChar(int beginChar) {

+        beginPos.setChar(beginChar);

+    }

+

+    public int getEndRun() {

+        return endPos.getRun();

+    }

+

+    public void setEndRun(int endRun) {

+        endPos.setRun(endRun);

+    }

+

+    public int getEndText() {

+        return endPos.getText();

+    }

+

+    public void setEndText(int endText) {

+        endPos.setText(endText);

+    }

+

+    public int getEndChar() {

+        return endPos.getChar();

+    }

+

+    public void setEndChar(int endChar) {

+        endPos.setChar(endChar);

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java
index 578dec3..9272ac0 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/UnderlinePatterns.java
@@ -19,13 +19,13 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/**
- * Specifies the types of patterns which may be used to create the underline
- * applied beneath the text in a run.
- * 
- * @author Gisella Bronzetti
- */
-public enum UnderlinePatterns {
+/**

+ * Specifies the types of patterns which may be used to create the underline

+ * applied beneath the text in a run.

+ *

+ * @author Gisella Bronzetti

+ */

+public enum UnderlinePatterns {

 
     /**
      * Specifies an underline consisting of a single line beneath all characters
@@ -132,31 +132,32 @@
 
     /**
      * Specifies no underline beneath this run.
-     */
-    NONE(18);
-
-    private final int value;
-
-    private UnderlinePatterns(int val) {
-       value = val;
-    }
-
-    public int getValue() {
-       return value;
-    }
-
-    private static Map<Integer, UnderlinePatterns> imap = new HashMap<Integer, UnderlinePatterns>();
-    static {
-       for (UnderlinePatterns p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static UnderlinePatterns valueOf(int type) {
-       UnderlinePatterns align = imap.get(new Integer(type));
-       if (align == null)
-          throw new IllegalArgumentException("Unknown underline pattern: "
-                + type);
-       return align;
-    }
-}
+     */

+    NONE(18);

+

+    private static Map<Integer, UnderlinePatterns> imap = new HashMap<Integer, UnderlinePatterns>();

+

+    static {

+        for (UnderlinePatterns p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private UnderlinePatterns(int val) {

+        value = val;

+    }

+

+    public static UnderlinePatterns valueOf(int type) {

+        UnderlinePatterns align = imap.get(new Integer(type));

+        if (align == null)

+            throw new IllegalArgumentException("Unknown underline pattern: "

+                    + type);

+        return align;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java
index 84ff628..4114c11 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/VerticalAlign.java
@@ -21,13 +21,13 @@
 
 /**
  * Specifies possible values for the alignment of the contents of this run in
- * relation to the default appearance of the run's text. This allows the text to
- * be repositioned as subscript or superscript without altering the font size of
- * the run properties.
- * 
- * @author Gisella Bronzetti
- */
-public enum VerticalAlign {
+ * relation to the default appearance of the run's text. This allows the text to

+ * be repositioned as subscript or superscript without altering the font size of

+ * the run properties.

+ *

+ * @author Gisella Bronzetti

+ */

+public enum VerticalAlign {

 
     /**
      * Specifies that the text in the parent run shall be located at the
@@ -44,31 +44,32 @@
      * Specifies that this text should be superscript. This setting shall raise
      * the text in this run above the baseline and change it to a smaller size,
      * if a smaller size is available.
-     */
-    SUBSCRIPT(3);
-
-    private final int value;
-
-    private VerticalAlign(int val) {
-       value = val;
-    }
-
-    public int getValue() {
-       return value;
-    }
-
-    private static Map<Integer, VerticalAlign> imap = new HashMap<Integer, VerticalAlign>();
-    static {
-       for (VerticalAlign p : values()) {
-          imap.put(new Integer(p.getValue()), p);
-       }
-    }
-
-    public static VerticalAlign valueOf(int type) {
-       VerticalAlign align = imap.get(new Integer(type));
-       if (align == null)
-          throw new IllegalArgumentException("Unknown vertical alignment: "
-                + type);
-       return align;
-    }
-}
+     */

+    SUBSCRIPT(3);

+

+    private static Map<Integer, VerticalAlign> imap = new HashMap<Integer, VerticalAlign>();

+

+    static {

+        for (VerticalAlign p : values()) {

+            imap.put(new Integer(p.getValue()), p);

+        }

+    }

+

+    private final int value;

+

+    private VerticalAlign(int val) {

+        value = val;

+    }

+

+    public static VerticalAlign valueOf(int type) {

+        VerticalAlign align = imap.get(new Integer(type));

+        if (align == null)

+            throw new IllegalArgumentException("Unknown vertical alignment: "

+                    + type);

+        return align;

+    }

+

+    public int getValue() {

+        return value;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
index 12d2d3a..8d4886b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
@@ -18,42 +18,43 @@
 package org.apache.poi.xwpf.usermodel;
 
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
-
-/**
- * @author Philipp Epp
- *
- */
-public class XWPFAbstractNum {
-	private CTAbstractNum ctAbstractNum;
-	protected XWPFNumbering numbering;
-	
-	 protected XWPFAbstractNum() {
-		 this.ctAbstractNum = null;
-		 this.numbering = null;
-		 
-	}
-	 public XWPFAbstractNum(CTAbstractNum abstractNum){
-		 this.ctAbstractNum = abstractNum;
-	 }
-	 
-	public XWPFAbstractNum(CTAbstractNum ctAbstractNum, XWPFNumbering numbering){
-		 this.ctAbstractNum  = ctAbstractNum;
-		 this.numbering = numbering;
-	 }
-	 public CTAbstractNum getAbstractNum(){
-		 return ctAbstractNum;
-	 }
-	 
-	 public XWPFNumbering getNumbering(){
-		 return numbering;
-	 }
-	 
-	 public CTAbstractNum getCTAbstractNum(){
-		 return ctAbstractNum;
-	 }
-	 
-	 public void setNumbering(XWPFNumbering numbering){
-		 this.numbering = numbering;
-	 }
-	 
-}
+

+/**

+ * @author Philipp Epp

+ */

+public class XWPFAbstractNum {

+    protected XWPFNumbering numbering;

+    private CTAbstractNum ctAbstractNum;

+

+    protected XWPFAbstractNum() {

+        this.ctAbstractNum = null;

+        this.numbering = null;

+

+    }

+

+    public XWPFAbstractNum(CTAbstractNum abstractNum) {

+        this.ctAbstractNum = abstractNum;

+    }

+

+    public XWPFAbstractNum(CTAbstractNum ctAbstractNum, XWPFNumbering numbering) {

+        this.ctAbstractNum = ctAbstractNum;

+        this.numbering = numbering;

+    }

+

+    public CTAbstractNum getAbstractNum() {

+        return ctAbstractNum;

+    }

+

+    public XWPFNumbering getNumbering() {

+        return numbering;

+    }

+

+    public void setNumbering(XWPFNumbering numbering) {

+        this.numbering = numbering;

+    }

+

+    public CTAbstractNum getCTAbstractNum() {

+        return ctAbstractNum;

+    }

+

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java
index 84ebc36..627971b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java
@@ -21,42 +21,35 @@
 
 /**
  * Sketch of XWPF comment class
- * 
-* @author Yury Batrakov (batrakov at gmail.com)
- * 
+ *
+ * @author Yury Batrakov (batrakov at gmail.com)
  */
-public class XWPFComment
-{
+public class XWPFComment {
     protected String id;
     protected String author;
     protected StringBuffer text;
-    
+
     @SuppressWarnings("deprecation")
-    public XWPFComment(CTComment comment, XWPFDocument document)
-    {
+    public XWPFComment(CTComment comment, XWPFDocument document) {
         text = new StringBuffer();
         id = comment.getId().toString();
         author = comment.getAuthor();
-        
-        for(CTP ctp : comment.getPArray())
-        {
+
+        for (CTP ctp : comment.getPArray()) {
             XWPFParagraph p = new XWPFParagraph(ctp, document);
             text.append(p.getText());
         }
     }
-    
-    public String getId()
-    {
+
+    public String getId() {
         return id;
     }
-    
-    public String getAuthor()
-    {
+
+    public String getAuthor() {
         return author;
     }
-    
-    public String getText()
-    {
+
+    public String getText() {
         return text.toString();
     }
 }
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java
similarity index 60%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java
index 48744ec..a430c87 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultParagraphStyle.java
@@ -1,22 +1,42 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xwpf.usermodel;
+
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
+
+/**
+ * Default Paragraph style, from which other styles will override
+ * TODO Share logic with {@link XWPFParagraph} which also uses CTPPr
+ */

+public class XWPFDefaultParagraphStyle {

+    private CTPPr ppr;

 

-       http://www.apache.org/licenses/LICENSE-2.0

+    public XWPFDefaultParagraphStyle(CTPPr ppr) {

+        this.ppr = ppr;

+    }

 

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

+    protected CTPPr getPPr() {

+        return ppr;

+    }

 

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+    public int getSpacingAfter() {

+        if (ppr.isSetSpacing())

+            return ppr.getSpacing().getAfter().intValue();

+        return -1;
+    }
+}
diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java
similarity index 61%
copy from src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
copy to src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java
index 48744ec..459335d 100644
--- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TableShape.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDefaultRunStyle.java
@@ -1,22 +1,42 @@
-/* ====================================================================

-   Licensed to the Apache Software Foundation (ASF) under one or more

-   contributor license agreements.  See the NOTICE file distributed with

-   this work for additional information regarding copyright ownership.

-   The ASF licenses this file to You under the Apache License, Version 2.0

-   (the "License"); you may not use this file except in compliance with

-   the License.  You may obtain a copy of the License at

+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xwpf.usermodel;
+
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
+
+/**
+ * Default Character Run style, from which other styles will override
+ * TODO Share logic with {@link XWPFRun} which also uses CTRPr
+ */

+public class XWPFDefaultRunStyle {

+    private CTRPr rpr;

 

-       http://www.apache.org/licenses/LICENSE-2.0

+    public XWPFDefaultRunStyle(CTRPr rpr) {

+        this.rpr = rpr;

+    }

 

-   Unless required by applicable law or agreed to in writing, software

-   distributed under the License is distributed on an "AS IS" BASIS,

-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-   See the License for the specific language governing permissions and

-   limitations under the License.

-==================================================================== */

+    protected CTRPr getRPr() {

+        return rpr;

+    }

 

-package org.apache.poi.sl.usermodel;

-

-public interface TableShape extends Shape {

-    // to be defined ...

-}

+    public int getFontSize() {

+        if (rpr.isSetSz())

+            return rpr.getSz().getVal().intValue() / 2;

+        return -1;
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index 9adc397..9eabdeb 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -76,23 +76,17 @@
 
 /**
  * <p>High(ish) level class for working with .docx files.</p>
- * 
+ * <p/>
  * <p>This class tries to hide some of the complexity
- *  of the underlying file format, but as it's not a 
- *  mature and stable API yet, certain parts of the
- *  XML structure come through. You'll therefore almost
- *  certainly need to refer to the OOXML specifications
- *  from
- *  http://www.ecma-international.org/publications/standards/Ecma-376.htm
- *  at some point in your use.</p>
+ * of the underlying file format, but as it's not a
+ * mature and stable API yet, certain parts of the
+ * XML structure come through. You'll therefore almost
+ * certainly need to refer to the OOXML specifications
+ * from
+ * http://www.ecma-international.org/publications/standards/Ecma-376.htm
+ * at some point in your use.</p>
  */
 public class XWPFDocument extends POIXMLDocument implements Document, IBody {
-    private CTDocument1 ctDocument;
-    private XWPFSettings settings;
-    /**
-     * Keeps track on all id-values used in this document and included parts, like headers, footers, etc.
-     */
-    private IdentifierManager drawingIdManager = new IdentifierManager(1L,4294967295L);
     protected List<XWPFFooter> footers = new ArrayList<XWPFFooter>();
     protected List<XWPFHeader> headers = new ArrayList<XWPFHeader>();
     protected List<XWPFComment> comments = new ArrayList<XWPFComment>();
@@ -107,8 +101,15 @@
     protected XWPFNumbering numbering;
     protected XWPFStyles styles;
     protected XWPFFootnotes footnotes;
-
-    /** Handles the joy of different headers/footers for different pages */
+    private CTDocument1 ctDocument;
+    private XWPFSettings settings;
+    /**
+     * Keeps track on all id-values used in this document and included parts, like headers, footers, etc.
+     */
+    private IdentifierManager drawingIdManager = new IdentifierManager(0L, 4294967295L);
+    /**
+     * Handles the joy of different headers/footers for different pages
+     */
     private XWPFHeaderFooterPolicy headerFooterPolicy;
 
     public XWPFDocument(OPCPackage pkg) throws IOException {
@@ -125,11 +126,32 @@
         load(XWPFFactory.getInstance());
     }
 
-    public XWPFDocument(){
+    public XWPFDocument() {
         super(newPackage());
         onDocumentCreate();
     }
 
+    /**
+     * Create a new WordProcessingML package and setup the default minimal content
+     */
+    protected static OPCPackage newPackage() {
+        try {
+            OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
+            // Main part
+            PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
+            // Create main part relationship
+            pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
+            // Create main document part
+            pkg.createPart(corePartName, XWPFRelation.DOCUMENT.getContentType());
+
+            pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
+
+            return pkg;
+        } catch (Exception e) {
+            throw new POIXMLException(e);
+        }
+    }
+
     @Override
     protected void onDocumentRead() throws IOException {
         try {
@@ -152,11 +174,11 @@
                     XWPFTable t = new XWPFTable((CTTbl) o, this);
                     bodyElements.add(t);
                     tables.add(t);
-                } else if (o instanceof CTSdtBlock){
-                   XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
-                   bodyElements.add(c);
-                   contentControls.add(c);
-               }
+                } else if (o instanceof CTSdtBlock) {
+                    XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this);
+                    bodyElements.add(c);
+                    contentControls.add(c);
+                }
             }
             cursor.dispose();
 
@@ -205,7 +227,7 @@
                             Method onDocumentRead = gp.getClass().getDeclaredMethod("onDocumentRead");
                             onDocumentRead.setAccessible(true);
                             onDocumentRead.invoke(gp);
-                        } catch(Exception e) {
+                        } catch (Exception e) {
                             throw new POIXMLException(e);
                         }
                     }
@@ -217,32 +239,32 @@
         }
     }
 
-    private void initHyperlinks(){
+    private void initHyperlinks() {
         // Get the hyperlinks
         // TODO: make me optional/separated in private function
         try {
             Iterator<PackageRelationship> relIter =
                     getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
-            while(relIter.hasNext()) {
+            while (relIter.hasNext()) {
                 PackageRelationship rel = relIter.next();
                 hyperlinks.add(new XWPFHyperlink(rel.getId(), rel.getTargetURI().toString()));
             }
-        } catch (InvalidFormatException e){
+        } catch (InvalidFormatException e) {
             throw new POIXMLException(e);
         }
     }
 
     @SuppressWarnings("deprecation")
     private void initFootnotes() throws XmlException, IOException {
-        for(POIXMLDocumentPart p : getRelations()){
+        for (POIXMLDocumentPart p : getRelations()) {
             String relation = p.getPackageRelationship().getRelationshipType();
             if (relation.equals(XWPFRelation.FOOTNOTE.getRelation())) {
-                this.footnotes = (XWPFFootnotes)p;
+                this.footnotes = (XWPFFootnotes) p;
                 this.footnotes.onDocumentRead();
-            } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){
+            } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())) {
                 EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream());
 
-                for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) {
+                for (CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) {
                     endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn));
                 }
             }
@@ -250,27 +272,6 @@
     }
 
     /**
-     * Create a new WordProcessingML package and setup the default minimal content
-     */
-    protected static OPCPackage newPackage() {
-        try {
-            OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
-            // Main part
-            PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
-            // Create main part relationship
-            pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
-            // Create main document part
-            pkg.createPart(corePartName, XWPFRelation.DOCUMENT.getContentType());
-
-            pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
-
-            return pkg;
-        } catch (Exception e){
-            throw new POIXMLException(e);
-        }
-    }
-
-    /**
      * Create a new CTWorkbook with all values set to default
      */
     @Override
@@ -278,7 +279,7 @@
         ctDocument = CTDocument1.Factory.newInstance();
         ctDocument.addNewBody();
 
-        settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS,XWPFFactory.getInstance());
+        settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS, XWPFFactory.getInstance());
 
         POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
         expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
@@ -298,6 +299,7 @@
 
     /**
      * returns an Iterator with paragraphs and tables
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
      */
     @Override
@@ -313,7 +315,7 @@
      * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs()
      */
     @Override
-    public List<XWPFParagraph> getParagraphs(){
+    public List<XWPFParagraph> getParagraphs() {
         return Collections.unmodifiableList(paragraphs);
     }
 
@@ -321,7 +323,7 @@
      * @see org.apache.poi.xwpf.usermodel.IBody#getTables()
      */
     @Override
-    public List<XWPFTable> getTables(){
+    public List<XWPFTable> getTables() {
         return Collections.unmodifiableList(tables);
     }
 
@@ -330,37 +332,35 @@
      */
     @Override
     public XWPFTable getTableArray(int pos) {
-        if (pos > 0 && pos < tables.size()){
+        if (pos > 0 && pos < tables.size()) {
             return tables.get(pos);
         }
         return null;
     }
 
     /**
-     * 
-     * @return  the list of footers
+     * @return the list of footers
      */
-    public List<XWPFFooter> getFooterList(){
+    public List<XWPFFooter> getFooterList() {
         return Collections.unmodifiableList(footers);
     }
 
-    public XWPFFooter getFooterArray(int pos){
+    public XWPFFooter getFooterArray(int pos) {
         return footers.get(pos);
     }
 
     /**
-     * 
-     * @return  the list of headers
+     * @return the list of headers
      */
-    public List<XWPFHeader> getHeaderList(){
+    public List<XWPFHeader> getHeaderList() {
         return Collections.unmodifiableList(headers);
     }
 
-    public XWPFHeader getHeaderArray(int pos){
+    public XWPFHeader getHeaderArray(int pos) {
         return headers.get(pos);
     }
 
-    public String getTblStyle(XWPFTable table){
+    public String getTblStyle(XWPFTable table) {
         return table.getStyleID();
     }
 
@@ -374,17 +374,17 @@
     }
 
     public XWPFFootnote getFootnoteByID(int id) {
-        if(footnotes == null) return null;
+        if (footnotes == null) return null;
         return footnotes.getFootnoteById(id);
     }
 
     public XWPFFootnote getEndnoteByID(int id) {
-        if(endnotes == null) return null;
+        if (endnotes == null) return null;
         return endnotes.get(id);
     }
 
     public List<XWPFFootnote> getFootnotes() {
-        if(footnotes == null) {
+        if (footnotes == null) {
             return Collections.emptyList();
         }
         return footnotes.getFootnotesList();
@@ -409,7 +409,7 @@
 
     /**
      * Get the document part that's defined as the
-     *  given relationship of the core document.
+     * given relationship of the core document.
      */
     public PackagePart getPartById(String id) {
         try {
@@ -422,7 +422,7 @@
 
     /**
      * Returns the policy on headers and footers, which
-     *  also provides a way to get at them.
+     * also provides a way to get at them.
      */
     public XWPFHeaderFooterPolicy getHeaderFooterPolicy() {
         return headerFooterPolicy;
@@ -436,10 +436,10 @@
         PackagePart[] parts;
         try {
             parts = getRelatedByType(XWPFRelation.STYLES.getRelation());
-        } catch(InvalidFormatException e) {
+        } catch (InvalidFormatException e) {
             throw new IllegalStateException(e);
         }
-        if(parts.length != 1) {
+        if (parts.length != 1) {
             throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length);
         }
 
@@ -471,57 +471,56 @@
      * Finds that for example the 2nd entry in the body list is the 1st paragraph
      */
     private int getBodyElementSpecificPos(int pos, List<? extends IBodyElement> list) {
-       // If there's nothing to find, skip it
-       if(list.size() == 0) {
-          return -1;
-       }
+        // If there's nothing to find, skip it
+        if (list.size() == 0) {
+            return -1;
+        }
 
-       if(pos >= 0 && pos < bodyElements.size()) {
-          // Ensure the type is correct
-          IBodyElement needle = bodyElements.get(pos);
-          if(needle.getElementType() != list.get(0).getElementType()) {
-             // Wrong type
-             return -1;
-          }
+        if (pos >= 0 && pos < bodyElements.size()) {
+            // Ensure the type is correct
+            IBodyElement needle = bodyElements.get(pos);
+            if (needle.getElementType() != list.get(0).getElementType()) {
+                // Wrong type
+                return -1;
+            }
 
-          // Work back until we find it
-          int startPos = Math.min(pos, list.size()-1);
-          for(int i=startPos; i>=0; i--) {
-             if(list.get(i) == needle) {
-                return i;
-             }
-          }
-       }
+            // Work back until we find it
+            int startPos = Math.min(pos, list.size() - 1);
+            for (int i = startPos; i >= 0; i--) {
+                if (list.get(i) == needle) {
+                    return i;
+                }
+            }
+        }
 
-       // Couldn't be found
-       return -1;
+        // Couldn't be found
+        return -1;
     }
-    
+
     /**
      * Look up the paragraph at the specified position in the body elements list
      * and return this paragraphs position in the paragraphs list
-     * 
-     * @param pos
-     *            The position of the relevant paragraph in the body elements
+     *
+     * @param pos The position of the relevant paragraph in the body elements
      *            list
      * @return the position of the paragraph in the paragraphs list, if there is
-     *         a paragraph at the position in the bodyelements list. Else it
-     *         will return -1
-     * 
+     * a paragraph at the position in the bodyelements list. Else it
+     * will return -1
      */
     public int getParagraphPos(int pos) {
-       return getBodyElementSpecificPos(pos, paragraphs);
+        return getBodyElementSpecificPos(pos, paragraphs);
     }
 
     /**
-     * get with the position of a table in the bodyelement array list 
+     * get with the position of a table in the bodyelement array list
      * the position of this table in the table array list
+     *
      * @param pos position of the table in the bodyelement array list
      * @return if there is a table at the position in the bodyelement array list,
-     *         else it will return null. 
+     * else it will return null.
      */
     public int getTablePos(int pos) {
-       return getBodyElementSpecificPos(pos, tables);
+        return getBodyElementSpecificPos(pos, tables);
     }
 
     /**
@@ -530,10 +529,10 @@
      * of the documents body. When this method is done, the cursor passed as
      * parameter points to the {@link org.apache.xmlbeans.XmlCursor.TokenType#END}
      * of the newly inserted paragraph.
-     * 
+     *
      * @param cursor
      * @return the {@link XWPFParagraph} object representing the newly inserted
-     *         CTP object
+     * CTP object
      */
     @Override
     public XWPFParagraph insertNewParagraph(XmlCursor cursor) {
@@ -635,8 +634,7 @@
                 cursor.toCursor(tableCursor);
                 cursor.toEndToken();
                 return newT;
-            }
-            finally {
+            } finally {
                 tableCursor.dispose();
             }
         }
@@ -645,6 +643,7 @@
 
     /**
      * verifies that cursor is on the right position
+     *
      * @param cursor
      */
     private boolean isCursorInBody(XmlCursor cursor) {
@@ -659,11 +658,11 @@
 
     private int getPosOfBodyElement(IBodyElement needle) {
         BodyElementType type = needle.getElementType();
-        IBodyElement current; 
-        for(int i=0; i<bodyElements.size(); i++) {
+        IBodyElement current;
+        for (int i = 0; i < bodyElements.size(); i++) {
             current = bodyElements.get(i);
-            if(current.getElementType() == type) {
-                if(current.equals(needle)) {
+            if (current.getElementType() == type) {
+                if (current.equals(needle)) {
                     return i;
                 }
             }
@@ -673,21 +672,23 @@
 
     /**
      * Get the position of the paragraph, within the list
-     *  of all the body elements.
+     * of all the body elements.
+     *
      * @param p The paragraph to find
-     * @return The location, or -1 if the paragraph couldn't be found 
+     * @return The location, or -1 if the paragraph couldn't be found
      */
-    public int getPosOfParagraph(XWPFParagraph p){
+    public int getPosOfParagraph(XWPFParagraph p) {
         return getPosOfBodyElement(p);
     }
 
     /**
      * Get the position of the table, within the list of
-     *  all the body elements.
+     * all the body elements.
+     *
      * @param t The table to find
      * @return The location, or -1 if the table couldn't be found
      */
-    public int getPosOfTable(XWPFTable t){
+    public int getPosOfTable(XWPFTable t) {
         return getPosOfBodyElement(t);
     }
 
@@ -718,23 +719,25 @@
 
     /**
      * Gets the index of the relation we're trying to create
+     *
      * @param relation
      * @return i
      */
     private int getRelationIndex(XWPFRelation relation) {
         List<POIXMLDocumentPart> relations = getRelations();
         int i = 1;
-        for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext() ; ) {
-           POIXMLDocumentPart item = it.next();
-           if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
-              i++;
-           }
+        for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext(); ) {
+            POIXMLDocumentPart item = it.next();
+            if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
+                i++;
+            }
         }
         return i;
     }
 
     /**
      * Appends a new paragraph to this document
+     *
      * @return a new paragraph
      */
     public XWPFParagraph createParagraph() {
@@ -746,16 +749,17 @@
 
     /**
      * Creates an empty numbering if one does not already exist and sets the numbering member
+     *
      * @return numbering
      */
     public XWPFNumbering createNumbering() {
-        if(numbering == null) {
+        if (numbering == null) {
             NumberingDocument numberingDoc = NumberingDocument.Factory.newInstance();
 
             XWPFRelation relation = XWPFRelation.NUMBERING;
             int i = getRelationIndex(relation);
 
-            XWPFNumbering wrapper = (XWPFNumbering)createRelationship(relation, XWPFFactory.getInstance(), i);
+            XWPFNumbering wrapper = (XWPFNumbering) createRelationship(relation, XWPFFactory.getInstance(), i);
             wrapper.setNumbering(numberingDoc.addNewNumbering());
             numbering = wrapper;
         }
@@ -765,61 +769,64 @@
 
     /**
      * Creates an empty styles for the document if one does not already exist
+     *
      * @return styles
      */
     public XWPFStyles createStyles() {
-       if(styles == null) {
-          StylesDocument stylesDoc = StylesDocument.Factory.newInstance();
+        if (styles == null) {
+            StylesDocument stylesDoc = StylesDocument.Factory.newInstance();
 
-          XWPFRelation relation = XWPFRelation.STYLES;
-          int i = getRelationIndex(relation);
+            XWPFRelation relation = XWPFRelation.STYLES;
+            int i = getRelationIndex(relation);
 
-          XWPFStyles wrapper = (XWPFStyles)createRelationship(relation, XWPFFactory.getInstance(), i);
-          wrapper.setStyles(stylesDoc.addNewStyles());
-          styles = wrapper;
-       }
+            XWPFStyles wrapper = (XWPFStyles) createRelationship(relation, XWPFFactory.getInstance(), i);
+            wrapper.setStyles(stylesDoc.addNewStyles());
+            styles = wrapper;
+        }
 
-       return styles;
+        return styles;
     }
 
     /**
      * Creates an empty footnotes element for the document if one does not already exist
+     *
      * @return footnotes
      */
     public XWPFFootnotes createFootnotes() {
-       if(footnotes == null) {
-          FootnotesDocument footnotesDoc = FootnotesDocument.Factory.newInstance();
+        if (footnotes == null) {
+            FootnotesDocument footnotesDoc = FootnotesDocument.Factory.newInstance();
 
-          XWPFRelation relation = XWPFRelation.FOOTNOTE;
-          int i = getRelationIndex(relation);
+            XWPFRelation relation = XWPFRelation.FOOTNOTE;
+            int i = getRelationIndex(relation);
 
-          XWPFFootnotes wrapper = (XWPFFootnotes)createRelationship(relation, XWPFFactory.getInstance(), i);
-          wrapper.setFootnotes(footnotesDoc.addNewFootnotes());
-          footnotes = wrapper;
-       }
+            XWPFFootnotes wrapper = (XWPFFootnotes) createRelationship(relation, XWPFFactory.getInstance(), i);
+            wrapper.setFootnotes(footnotesDoc.addNewFootnotes());
+            footnotes = wrapper;
+        }
 
-       return footnotes;
+        return footnotes;
     }
 
     public XWPFFootnote addFootnote(CTFtnEdn note) {
-       return footnotes.addFootnote(note);
+        return footnotes.addFootnote(note);
     }
 
     public XWPFFootnote addEndnote(CTFtnEdn note) {
-       XWPFFootnote endnote = new XWPFFootnote(this, note); 
-       endnotes.put(note.getId().intValue(), endnote);
-       return endnote;
+        XWPFFootnote endnote = new XWPFFootnote(this, note);
+        endnotes.put(note.getId().intValue(), endnote);
+        return endnote;
     }
 
     /**
-     * remove a BodyElement from bodyElements array list 
+     * remove a BodyElement from bodyElements array list
+     *
      * @param pos
      * @return true if removing was successfully, else return false
      */
     public boolean removeBodyElement(int pos) {
         if (pos >= 0 && pos < bodyElements.size()) {
-            BodyElementType type = bodyElements.get(pos).getElementType(); 
-            if (type == BodyElementType.TABLE){
+            BodyElementType type = bodyElements.get(pos).getElementType();
+            if (type == BodyElementType.TABLE) {
                 int tablePos = getTablePos(pos);
                 tables.remove(tablePos);
                 ctDocument.getBody().removeTbl(tablePos);
@@ -830,13 +837,14 @@
                 ctDocument.getBody().removeP(paraPos);
             }
             bodyElements.remove(pos);
-            return true;            
+            return true;
         }
         return false;
     }
 
     /**
      * copies content of a paragraph to a existing paragraph in the list paragraphs at position pos
+     *
      * @param paragraph
      * @param pos
      */
@@ -859,6 +867,7 @@
 
     /**
      * Create an empty table with one row and one column as default.
+     *
      * @return a new table
      */
     public XWPFTable createTable() {
@@ -870,19 +879,20 @@
 
     /**
      * Create an empty table with a number of rows and cols specified
+     *
      * @param rows
      * @param cols
      * @return table
      */
     public XWPFTable createTable(int rows, int cols) {
-       XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols);
-       bodyElements.add(table);
-       tables.add(table);
-       return table;
+        XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols);
+        bodyElements.add(table);
+        tables.add(table);
+        return table;
     }
 
     /**
-     * 
+     *
      */
     public void createTOC() {
         CTSdtBlock block = this.getDocument().getBody().addNewSdt();
@@ -900,7 +910,9 @@
         }
     }
 
-    /**Replace content of table in array tables at position pos with a
+    /**
+     * Replace content of table in array tables at position pos with a
+     *
      * @param pos
      * @param table
      */
@@ -919,7 +931,7 @@
      *     &lt;w:settings  ... &gt;
      *         &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
      * </pre>
-     * 
+     *
      * @return true if documentProtection is enforced with option readOnly
      */
     public boolean isEnforcedReadonlyProtection() {
@@ -936,7 +948,7 @@
      *     &lt;w:settings  ... &gt;
      *         &lt;w:documentProtection w:edit=&quot;forms&quot; w:enforcement=&quot;1&quot;/&gt;
      * </pre>
-     * 
+     *
      * @return true if documentProtection is enforced with option forms
      */
     public boolean isEnforcedFillingFormsProtection() {
@@ -953,7 +965,7 @@
      *     &lt;w:settings  ... &gt;
      *         &lt;w:documentProtection w:edit=&quot;comments&quot; w:enforcement=&quot;1&quot;/&gt;
      * </pre>
-     * 
+     *
      * @return true if documentProtection is enforced with option comments
      */
     public boolean isEnforcedCommentsProtection() {
@@ -970,7 +982,7 @@
      *     &lt;w:settings  ... &gt;
      *         &lt;w:documentProtection w:edit=&quot;trackedChanges&quot; w:enforcement=&quot;1&quot;/&gt;
      * </pre>
-     * 
+     *
      * @return true if documentProtection is enforced with option trackedChanges
      */
     public boolean isEnforcedTrackedChangesProtection() {
@@ -1002,21 +1014,21 @@
      * <br/>
      * sample snippet from settings.xml
      * <pre>
-     *   &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot; 
+     *   &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;
      *       w:cryptProviderType=&quot;rsaAES&quot; w:cryptAlgorithmClass=&quot;hash&quot;
      *       w:cryptAlgorithmType=&quot;typeAny&quot; w:cryptAlgorithmSid=&quot;14&quot;
      *       w:cryptSpinCount=&quot;100000&quot; w:hash=&quot;...&quot; w:salt=&quot;....&quot;
      *   /&gt;
      * </pre>
-     * 
+     *
      * @param password the plaintext password, if null no password will be applied
      * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
-     *   if null, it will default default to sha1
+     *                 if null, it will default default to sha1
      */
     public void enforceReadonlyProtection(String password, HashAlgorithm hashAlgo) {
         settings.setEnforcementEditValue(STDocProtect.READ_ONLY, password, hashAlgo);
     }
-    
+
     /**
      * Enforce the Filling Forms protection.<br/>
      * In the documentProtection tag inside settings.xml file, <br/>
@@ -1038,21 +1050,21 @@
      * <br/>
      * sample snippet from settings.xml
      * <pre>
-     *   &lt;w:documentProtection w:edit=&quot;forms&quot; w:enforcement=&quot;1&quot; 
+     *   &lt;w:documentProtection w:edit=&quot;forms&quot; w:enforcement=&quot;1&quot;
      *       w:cryptProviderType=&quot;rsaAES&quot; w:cryptAlgorithmClass=&quot;hash&quot;
      *       w:cryptAlgorithmType=&quot;typeAny&quot; w:cryptAlgorithmSid=&quot;14&quot;
      *       w:cryptSpinCount=&quot;100000&quot; w:hash=&quot;...&quot; w:salt=&quot;....&quot;
      *   /&gt;
      * </pre>
-     * 
+     *
      * @param password the plaintext password, if null no password will be applied
      * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
-     *   if null, it will default default to sha1
+     *                 if null, it will default default to sha1
      */
     public void enforceFillingFormsProtection(String password, HashAlgorithm hashAlgo) {
         settings.setEnforcementEditValue(STDocProtect.FORMS, password, hashAlgo);
     }
-    
+
     /**
      * Enforce the Comments protection.<br/>
      * In the documentProtection tag inside settings.xml file,<br/>
@@ -1074,21 +1086,21 @@
      * <br/>
      * sample snippet from settings.xml
      * <pre>
-     *   &lt;w:documentProtection w:edit=&quot;comments&quot; w:enforcement=&quot;1&quot; 
+     *   &lt;w:documentProtection w:edit=&quot;comments&quot; w:enforcement=&quot;1&quot;
      *       w:cryptProviderType=&quot;rsaAES&quot; w:cryptAlgorithmClass=&quot;hash&quot;
      *       w:cryptAlgorithmType=&quot;typeAny&quot; w:cryptAlgorithmSid=&quot;14&quot;
      *       w:cryptSpinCount=&quot;100000&quot; w:hash=&quot;...&quot; w:salt=&quot;....&quot;
      *   /&gt;
      * </pre>
-     * 
+     *
      * @param password the plaintext password, if null no password will be applied
      * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
-     *   if null, it will default default to sha1
+     *                 if null, it will default default to sha1
      */
     public void enforceCommentsProtection(String password, HashAlgorithm hashAlgo) {
         settings.setEnforcementEditValue(STDocProtect.COMMENTS, password, hashAlgo);
     }
-    
+
     /**
      * Enforce the Tracked Changes protection.<br/>
      * In the documentProtection tag inside settings.xml file, <br/>
@@ -1110,16 +1122,16 @@
      * <br/>
      * sample snippet from settings.xml
      * <pre>
-     *   &lt;w:documentProtection w:edit=&quot;trackedChanges&quot; w:enforcement=&quot;1&quot; 
+     *   &lt;w:documentProtection w:edit=&quot;trackedChanges&quot; w:enforcement=&quot;1&quot;
      *       w:cryptProviderType=&quot;rsaAES&quot; w:cryptAlgorithmClass=&quot;hash&quot;
      *       w:cryptAlgorithmType=&quot;typeAny&quot; w:cryptAlgorithmSid=&quot;14&quot;
      *       w:cryptSpinCount=&quot;100000&quot; w:hash=&quot;...&quot; w:salt=&quot;....&quot;
      *   /&gt;
      * </pre>
-     * 
+     *
      * @param password the plaintext password, if null no password will be applied
      * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
-     *   if null, it will default default to sha1
+     *                 if null, it will default default to sha1
      */
     public void enforceTrackedChangesProtection(String password, HashAlgorithm hashAlgo) {
         settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES, password, hashAlgo);
@@ -1134,7 +1146,7 @@
     public boolean validateProtectionPassword(String password) {
         return settings.validateProtectionPassword(password);
     }
-    
+
     /**
      * Remove protection enforcement.<br/>
      * In the documentProtection tag inside settings.xml file <br/>
@@ -1148,38 +1160,39 @@
      * Enforces fields update on document open (in Word).
      * In the settings.xml file <br/>
      * sets the updateSettings value to true (w:updateSettings w:val="true")
-     * 
-     *  NOTICES:
-     *  <ul>
-     *   <li>Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?"
-     *       (if "Update automatic links at open" is enabled)</li>
-     *   <li>Flag is removed after saving with changes in Word </li>
-     *  </ul> 
+     * <p/>
+     * NOTICES:
+     * <ul>
+     * <li>Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?"
+     * (if "Update automatic links at open" is enabled)</li>
+     * <li>Flag is removed after saving with changes in Word </li>
+     * </ul>
      */
     public void enforceUpdateFields() {
         settings.setUpdateFields();
     }
-    
+
     /**
-      * Check if revision tracking is turned on.
-      * 
-      * @return <code>true</code> if revision tracking is turned on
-      */
-     public boolean isTrackRevisions() {
-         return settings.isTrackRevisions();
-     }
-    
-     /**
-      * Enable or disable revision tracking.
-      * 
-      * @param enable <code>true</code> to turn on revision tracking, <code>false</code> to turn off revision tracking
-      */
-     public void setTrackRevisions(boolean enable) {
-         settings.setTrackRevisions(enable);
-     }
+     * Check if revision tracking is turned on.
+     *
+     * @return <code>true</code> if revision tracking is turned on
+     */
+    public boolean isTrackRevisions() {
+        return settings.isTrackRevisions();
+    }
+
+    /**
+     * Enable or disable revision tracking.
+     *
+     * @param enable <code>true</code> to turn on revision tracking, <code>false</code> to turn off revision tracking
+     */
+    public void setTrackRevisions(boolean enable) {
+        settings.setTrackRevisions(enable);
+    }
 
     /**
      * inserts an existing XWPFTable to the arrays bodyElements and tables
+     *
      * @param pos
      * @param table
      */
@@ -1199,6 +1212,7 @@
 
     /**
      * Returns all Pictures, which are referenced from the document itself.
+     *
      * @return a {@link List} of {@link XWPFPictureData}. The returned {@link List} is unmodifiable. Use #a
      */
     public List<XWPFPictureData> getAllPictures() {
@@ -1223,14 +1237,12 @@
             list = new ArrayList<XWPFPictureData>(1);
             packagePictures.put(picData.getChecksum(), list);
         }
-        if (!list.contains(picData))
-        {
+        if (!list.contains(picData)) {
             list.add(picData);
         }
     }
-    
-    XWPFPictureData findPackagePictureData(byte[] pictureData, int format)
-    {
+
+    XWPFPictureData findPackagePictureData(byte[] pictureData, int format) {
         long checksum = IOUtils.calculateChecksum(pictureData);
         XWPFPictureData xwpfPicData = null;
         /*
@@ -1246,20 +1258,18 @@
                     xwpfPicData = curElem;
                 }
             }
-        } 
+        }
         return xwpfPicData;
     }
 
-    public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
-    {
+    public String addPictureData(byte[] pictureData, int format) throws InvalidFormatException {
         XWPFPictureData xwpfPicData = findPackagePictureData(pictureData, format);
         POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
-        
-        if (xwpfPicData == null)
-        {
+
+        if (xwpfPicData == null) {
             /* Part doesn't exist, create a new one */
             int idx = getNextPicNameNumber(format);
-            xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
+            xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(), idx);
             /* write bytes to new part */
             PackagePart picDataPart = xwpfPicData.getPackagePart();
             OutputStream out = null;
@@ -1278,11 +1288,9 @@
 
             registerPackagePictureData(xwpfPicData);
             pictures.add(xwpfPicData);
-            
+
             return getRelationId(xwpfPicData);
-        }
-        else if (!getRelations().contains(xwpfPicData))
-        {
+        } else if (!getRelations().contains(xwpfPicData)) {
             /*
              * Part already existed, but was not related so far. Create
              * relationship to the already existing part and update
@@ -1293,21 +1301,18 @@
             TargetMode targetMode = TargetMode.INTERNAL;
             PackagePartName partName = picDataPart.getPartName();
             String relation = relDesc.getRelation();
-            PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
+            PackageRelationship relShip = getPackagePart().addRelationship(partName, targetMode, relation);
             String id = relShip.getId();
-            addRelation(id,xwpfPicData);
+            addRelation(id, xwpfPicData);
             pictures.add(xwpfPicData);
             return id;
-        }
-        else 
-        {
+        } else {
             /* Part already existed, get relation id and return it */
             return getRelationId(xwpfPicData);
         }
     }
-    
-    public String addPictureData(InputStream is,int format) throws InvalidFormatException
-    {
+
+    public String addPictureData(InputStream is, int format) throws InvalidFormatException {
         try {
             byte[] data = IOUtils.toByteArray(is);
             return addPictureData(data, format);
@@ -1318,9 +1323,10 @@
 
     /**
      * get the next free ImageNumber
+     *
      * @param format
      * @return the next free ImageNumber
-     * @throws InvalidFormatException 
+     * @throws InvalidFormatException
      */
     public int getNextPicNameNumber(int format) throws InvalidFormatException {
         int img = getAllPackagePictures().size() + 1;
@@ -1336,6 +1342,7 @@
 
     /**
      * returns the PictureData by blipID
+     *
      * @param blipID
      * @return XWPFPictureData of a specificID
      */
@@ -1350,6 +1357,7 @@
 
     /**
      * getNumbering
+     *
      * @return numbering
      */
     public XWPFNumbering getNumbering() {
@@ -1358,6 +1366,7 @@
 
     /**
      * get Styles
+     *
      * @return styles for this document
      */
     public XWPFStyles getStyles() {
@@ -1366,7 +1375,7 @@
 
     /**
      * get the paragraph with the CTP class p
-     * 
+     *
      * @param p
      * @return the paragraph with the CTP class p
      */
@@ -1382,9 +1391,10 @@
 
     /**
      * get a table by its CTTbl-Object
+     *
      * @param ctTbl
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
      * @return a table by its CTTbl-Object or null
+     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
      */
     @Override
     public XWPFTable getTable(CTTbl ctTbl) {
@@ -1406,6 +1416,7 @@
 
     /**
      * Returns the paragraph that of position pos
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)
      */
     @Override
@@ -1420,6 +1431,7 @@
      * returns the Part, to which the body belongs, which you need for adding relationship to other parts
      * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
      * belongs.
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
      */
     @Override
@@ -1441,6 +1453,7 @@
 
     /**
      * get the TableCell which belongs to the TableCell
+     *
      * @param cell
      */
     @Override
@@ -1448,19 +1461,19 @@
         XmlCursor cursor = cell.newCursor();
         cursor.toParent();
         XmlObject o = cursor.getObject();
-        if(!(o instanceof CTRow)){
+        if (!(o instanceof CTRow)) {
             return null;
         }
-        CTRow row = (CTRow)o;
+        CTRow row = (CTRow) o;
         cursor.toParent();
         o = cursor.getObject();
         cursor.dispose();
-        if(! (o instanceof CTTbl)){
+        if (!(o instanceof CTTbl)) {
             return null;
         }
         CTTbl tbl = (CTTbl) o;
         XWPFTable table = getTable(tbl);
-        if(table == null){
+        if (table == null) {
             return null;
         }
         XWPFTableRow tableRow = table.getRow(row);
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java
index c6b2c2d..4fb02ce 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java
@@ -28,30 +28,29 @@
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
-/**
- * @author Yegor Kozlov
- */
-public final class XWPFFactory extends POIXMLFactory  {
-
-    private static final POILogger logger = POILogFactory.getLogger(XWPFFactory.class);
-
-    private XWPFFactory(){
-
-    }
-
-    private static final XWPFFactory inst = new XWPFFactory();
-
-    public static XWPFFactory getInstance(){
-        return inst;
-    }
-
-    @Override
-    public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){
-        POIXMLRelation descriptor = XWPFRelation.getInstance(rel.getRelationshipType());
-        if(descriptor == null || descriptor.getRelationClass() == null){
-            logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
-            return new POIXMLDocumentPart(part, rel);
-        }
+/**

+ * @author Yegor Kozlov

+ */

+public final class XWPFFactory extends POIXMLFactory {

+

+    private static final POILogger logger = POILogFactory.getLogger(XWPFFactory.class);

+    private static final XWPFFactory inst = new XWPFFactory();

+

+    private XWPFFactory() {

+

+    }

+

+    public static XWPFFactory getInstance() {

+        return inst;

+    }

+

+    @Override

+    public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part) {

+        POIXMLRelation descriptor = XWPFRelation.getInstance(rel.getRelationshipType());

+        if (descriptor == null || descriptor.getRelationClass() == null) {

+            logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());

+            return new POIXMLDocumentPart(part, rel);

+        }

 
         try {
             Class<? extends POIXMLDocumentPart> cls = descriptor.getRelationClass();
@@ -59,23 +58,23 @@
                 Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(POIXMLDocumentPart.class, PackagePart.class, PackageRelationship.class);
                 return constructor.newInstance(parent, part, rel);
             } catch (NoSuchMethodException e) {
-                Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
-                return constructor.newInstance(part, rel);
-            }
-        } catch (Exception e){
-            throw new POIXMLException(e);
-        }
-    }
-
-    @Override
-    public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
-        try {
-            Class<? extends POIXMLDocumentPart> cls = descriptor.getRelationClass();
-            Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
-            return constructor.newInstance();
-        } catch (Exception e){
-            throw new POIXMLException(e);
-        }
-    }
+                Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);

+                return constructor.newInstance(part, rel);

+            }

+        } catch (Exception e) {

+            throw new POIXMLException(e);

+        }

+    }

+

+    @Override

+    public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor) {

+        try {

+            Class<? extends POIXMLDocumentPart> cls = descriptor.getRelationClass();

+            Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();

+            return constructor.newInstance();

+        } catch (Exception e) {

+            throw new POIXMLException(e);

+        }

+    }

 
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
index 8485f1d..8ae3326 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
@@ -53,16 +53,16 @@
         while (cursor.toNextSelection()) {
             XmlObject o = cursor.getObject();
             if (o instanceof CTP) {
-                XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                XWPFParagraph p = new XWPFParagraph((CTP) o, this);
                 paragraphs.add(p);
                 bodyElements.add(p);
             }
             if (o instanceof CTTbl) {
-                XWPFTable t = new XWPFTable((CTTbl)o, this);
+                XWPFTable t = new XWPFTable((CTTbl) o, this);
                 tables.add(t);
                 bodyElements.add(t);
             }
-            
+
         }
         cursor.dispose();
     }
@@ -78,7 +78,7 @@
     protected void commit() throws IOException {
         XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
         xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "ftr"));
-        Map<String,String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<String, String>();
         map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
         map.put("urn:schemas-microsoft-com:office:office", "o");
         map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
@@ -95,8 +95,8 @@
         out.close();
     }
 
-    @Override  
-    protected void onDocumentRead() throws IOException{
+    @Override
+    protected void onDocumentRead() throws IOException {
         super.onDocumentRead();
         FtrDocument ftrDocument = null;
         InputStream is;
@@ -111,19 +111,19 @@
             while (cursor.toNextSelection()) {
                 XmlObject o = cursor.getObject();
                 if (o instanceof CTP) {
-                    XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                    XWPFParagraph p = new XWPFParagraph((CTP) o, this);
                     paragraphs.add(p);
                     bodyElements.add(p);
                 }
                 if (o instanceof CTTbl) {
-                    XWPFTable t = new XWPFTable((CTTbl)o, this);
+                    XWPFTable t = new XWPFTable((CTTbl) o, this);
                     tables.add(t);
                     bodyElements.add(t);
                 }
-                if (o instanceof CTSdtBlock){
-                   XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
-                   bodyElements.add(c);
-               }
+                if (o instanceof CTSdtBlock) {
+                    XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this);
+                    bodyElements.add(c);
+                }
             }
             cursor.dispose();
         } catch (Exception e) {
@@ -133,6 +133,7 @@
 
     /**
      * get the PartType of the body
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
      */
     public BodyType getPartType() {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
index 5f0367d..7b51ed4 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
@@ -27,64 +27,64 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
-
-public class XWPFFootnote implements Iterable<XWPFParagraph>,IBody {
-    private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
-    private List<XWPFTable> tables= new ArrayList<XWPFTable>();
-    private List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
-    private List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
-
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;

+

+public class XWPFFootnote implements Iterable<XWPFParagraph>, IBody {

+    private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();

+    private List<XWPFTable> tables = new ArrayList<XWPFTable>();

+    private List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();

+    private List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();

+

     private CTFtnEdn ctFtnEdn;
     private XWPFFootnotes footnotes;
-    private XWPFDocument document;
-
-    public XWPFFootnote(CTFtnEdn note, XWPFFootnotes xFootnotes) {
-       footnotes = xFootnotes;
-       ctFtnEdn = note;
-       document = xFootnotes.getXWPFDocument();
-       init();
-    }
-
-    public XWPFFootnote(XWPFDocument document, CTFtnEdn body) {
-       ctFtnEdn = body;
-       this.document = document;
-       init();
-    }
-    
-    private void init(){
-       XmlCursor cursor = ctFtnEdn.newCursor();
-       //copied from XWPFDocument...should centralize this code
-       //to avoid duplication
-       cursor.selectPath("./*");
-       while (cursor.toNextSelection()) {
-           XmlObject o = cursor.getObject();
-           if (o instanceof CTP) {
-               XWPFParagraph p = new XWPFParagraph((CTP) o, this);
-               bodyElements.add(p);
-               paragraphs.add(p);
-           } else if (o instanceof CTTbl) {
-               XWPFTable t = new XWPFTable((CTTbl) o, this);
-               bodyElements.add(t);
-               tables.add(t);
-           } else if (o instanceof CTSdtBlock){
-               XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
-               bodyElements.add(c);
-           }
-
-       }
-       cursor.dispose();
-   }
-
-    public List<XWPFParagraph> getParagraphs() {
-        return paragraphs;
-    }
-
-    public Iterator<XWPFParagraph> iterator(){
-        return paragraphs.iterator();
-    }
-
+    private XWPFDocument document;

+

+    public XWPFFootnote(CTFtnEdn note, XWPFFootnotes xFootnotes) {

+        footnotes = xFootnotes;

+        ctFtnEdn = note;

+        document = xFootnotes.getXWPFDocument();

+        init();

+    }

+

+    public XWPFFootnote(XWPFDocument document, CTFtnEdn body) {

+        ctFtnEdn = body;

+        this.document = document;

+        init();

+    }

+

+    private void init() {

+        XmlCursor cursor = ctFtnEdn.newCursor();

+        //copied from XWPFDocument...should centralize this code

+        //to avoid duplication

+        cursor.selectPath("./*");

+        while (cursor.toNextSelection()) {

+            XmlObject o = cursor.getObject();

+            if (o instanceof CTP) {

+                XWPFParagraph p = new XWPFParagraph((CTP) o, this);

+                bodyElements.add(p);

+                paragraphs.add(p);

+            } else if (o instanceof CTTbl) {

+                XWPFTable t = new XWPFTable((CTTbl) o, this);

+                bodyElements.add(t);

+                tables.add(t);

+            } else if (o instanceof CTSdtBlock) {

+                XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this);

+                bodyElements.add(c);

+            }

+

+        }

+        cursor.dispose();

+    }

+

+    public List<XWPFParagraph> getParagraphs() {

+        return paragraphs;

+    }

+

+    public Iterator<XWPFParagraph> iterator() {

+        return paragraphs.iterator();

+    }

+

     public List<XWPFTable> getTables() {
         return tables;
     }
@@ -95,226 +95,231 @@
 
     public List<IBodyElement> getBodyElements() {
         return bodyElements;
-    }
-
-    public CTFtnEdn getCTFtnEdn() {
-       return ctFtnEdn;
-    }
-
-    public void setCTFtnEdn(CTFtnEdn footnote) {
-       ctFtnEdn = footnote;
-    }
-
-    /**
+    }

+

+    public CTFtnEdn getCTFtnEdn() {

+        return ctFtnEdn;

+    }

+

+    public void setCTFtnEdn(CTFtnEdn footnote) {

+        ctFtnEdn = footnote;

+    }

+

+    /**

      * @param pos in table array
      * @return The table at position pos
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
-     */
-    public XWPFTable getTableArray(int pos) {
-        if(pos > 0 && pos < tables.size()){
-            return tables.get(pos);
-        }
-        return null;
+     * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)

+     */

+    public XWPFTable getTableArray(int pos) {

+        if (pos > 0 && pos < tables.size()) {

+            return tables.get(pos);

+        }

+        return null;

     }
-
-    /**
-     * inserts an existing XWPFTable to the arrays bodyElements and tables
-     * @param pos
-     * @param table
-     * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table)
+

+    /**

+     * inserts an existing XWPFTable to the arrays bodyElements and tables

+     *

+     * @param pos

+     * @param table

+     * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table)

      */
     @SuppressWarnings("deprecation")
     public void insertTable(int pos, XWPFTable table) {
-        bodyElements.add(pos, table);
-        int i = 0;
-        for (CTTbl tbl : ctFtnEdn.getTblArray()) {
-            if(tbl == table.getCTTbl()){
-                break;
-            }
-            i++;
+        bodyElements.add(pos, table);

+        int i = 0;

+        for (CTTbl tbl : ctFtnEdn.getTblArray()) {

+            if (tbl == table.getCTTbl()) {

+                break;

+            }

+            i++;

         }
         tables.add(i, table);
 
     }
 
-    /**
-     * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header
-     * the method will return this table
-     * if there is no corresponding {@link XWPFTable} the method will return null 
-     * @param ctTable
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable)
-     */
-    public XWPFTable getTable(CTTbl ctTable){
-        for (XWPFTable table : tables) {
-            if(table==null)
-                return null;
-            if(table.getCTTbl().equals(ctTable))
-                return table;
-        }
-        return null;
+    /**

+     * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header

+     * the method will return this table

+     * if there is no corresponding {@link XWPFTable} the method will return null

+     *

+     * @param ctTable

+     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable)

+     */

+    public XWPFTable getTable(CTTbl ctTable) {

+        for (XWPFTable table : tables) {

+            if (table == null)

+                return null;

+            if (table.getCTTbl().equals(ctTable))

+                return table;

+        }

+        return null;

     }
 
-    /**
-     * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer
-     * the method will return this paragraph
-     * if there is no corresponding {@link XWPFParagraph} the method will return null 
-     * @param p is instance of CTP and is searching for an XWPFParagraph
-     * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer
-     * 		   XWPFParagraph with the correspondig CTP p
-     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p)
-     */
-    public XWPFParagraph getParagraph(CTP p){
-        for (XWPFParagraph paragraph : paragraphs) {
-            if(paragraph.getCTP().equals(p))
-                return paragraph;
-        }
-        return null;
+    /**

+     * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer

+     * the method will return this paragraph

+     * if there is no corresponding {@link XWPFParagraph} the method will return null

+     *

+     * @param p is instance of CTP and is searching for an XWPFParagraph

+     * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer

+     * XWPFParagraph with the correspondig CTP p

+     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p)

+     */

+    public XWPFParagraph getParagraph(CTP p) {

+        for (XWPFParagraph paragraph : paragraphs) {

+            if (paragraph.getCTP().equals(p))

+                return paragraph;

+        }

+        return null;

     }
-
-    /**
-     * Returns the paragraph that holds
-     *  the text of the header or footer.
-     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos)
-     */
-    public XWPFParagraph getParagraphArray(int pos) {
+

+    /**

+     * Returns the paragraph that holds

+     * the text of the header or footer.

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos)

+     */

+    public XWPFParagraph getParagraphArray(int pos) {

 
         return paragraphs.get(pos);
     }
-
-    /**
-     * get the TableCell which belongs to the TableCell
-     * @param cell
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell)
-     */
+

+    /**

+     * get the TableCell which belongs to the TableCell

+     *

+     * @param cell

+     * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell)

+     */

     public XWPFTableCell getTableCell(CTTc cell) {
-        XmlCursor cursor = cell.newCursor();
-        cursor.toParent();
-        XmlObject o = cursor.getObject();
-        if(!(o instanceof CTRow)){
-            return null;
-        }
-        CTRow row = (CTRow)o;
-        cursor.toParent();
-        o = cursor.getObject();
-        cursor.dispose();
-        if(! (o instanceof CTTbl)){
-            return null;
-        }
-        CTTbl tbl = (CTTbl) o;
-        XWPFTable table = getTable(tbl);
-        if(table == null){
-            return null;
-        }
-        XWPFTableRow tableRow = table.getRow(row);
-        if(row == null){
-            return null;
-        }
-        return tableRow.getTableCell(cell);
+        XmlCursor cursor = cell.newCursor();

+        cursor.toParent();

+        XmlObject o = cursor.getObject();

+        if (!(o instanceof CTRow)) {

+            return null;

+        }

+        CTRow row = (CTRow) o;

+        cursor.toParent();

+        o = cursor.getObject();

+        cursor.dispose();

+        if (!(o instanceof CTTbl)) {

+            return null;

+        }

+        CTTbl tbl = (CTTbl) o;

+        XWPFTable table = getTable(tbl);

+        if (table == null) {

+            return null;

+        }

+        XWPFTableRow tableRow = table.getRow(row);

+        if (row == null) {

+            return null;

+        }

+        return tableRow.getTableCell(cell);

     }
-
-    /**
-     * verifies that cursor is on the right position
-     * @param cursor
-     */
-    private boolean isCursorInFtn(XmlCursor cursor) {
-        XmlCursor verify = cursor.newCursor();
-        verify.toParent();
-        if(verify.getObject() == this.ctFtnEdn){
-            return true;
-        }
-        return false;
-    }
-
-    public POIXMLDocumentPart getOwner(){
-        return footnotes;
-    }
-
-    /**
-     * 
-     * @param cursor
-     * @return the inserted table
-     * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor)
-     */
-    public XWPFTable insertNewTbl(XmlCursor cursor) {
-        if(isCursorInFtn(cursor)){
-            String uri = CTTbl.type.getName().getNamespaceURI();
-            String localPart = "tbl";
-            cursor.beginElement(localPart,uri);
-            cursor.toParent();
-            CTTbl t = (CTTbl)cursor.getObject();
-            XWPFTable newT = new XWPFTable(t, this);
-            cursor.removeXmlContents();
-            XmlObject o = null;
-            while(!(o instanceof CTTbl)&&(cursor.toPrevSibling())){
-                o = cursor.getObject();
-            }
-            if(!(o instanceof CTTbl)){
-                tables.add(0, newT);
-            }
-            else{
-                int pos = tables.indexOf(getTable((CTTbl)o))+1;
-                tables.add(pos,newT);
-            }
-            int i=0;
-            cursor = t.newCursor();
-            while(cursor.toPrevSibling()){
-                o =cursor.getObject();
-                if(o instanceof CTP || o instanceof CTTbl)
-                    i++;
-            }
-            bodyElements.add(i, newT);
+

+    /**

+     * verifies that cursor is on the right position

+     *

+     * @param cursor

+     */

+    private boolean isCursorInFtn(XmlCursor cursor) {

+        XmlCursor verify = cursor.newCursor();

+        verify.toParent();

+        if (verify.getObject() == this.ctFtnEdn) {

+            return true;

+        }

+        return false;

+    }

+

+    public POIXMLDocumentPart getOwner() {

+        return footnotes;

+    }

+

+    /**

+     * @param cursor

+     * @return the inserted table

+     * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor)

+     */

+    public XWPFTable insertNewTbl(XmlCursor cursor) {

+        if (isCursorInFtn(cursor)) {

+            String uri = CTTbl.type.getName().getNamespaceURI();

+            String localPart = "tbl";

+            cursor.beginElement(localPart, uri);

+            cursor.toParent();

+            CTTbl t = (CTTbl) cursor.getObject();

+            XWPFTable newT = new XWPFTable(t, this);

+            cursor.removeXmlContents();

+            XmlObject o = null;

+            while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) {

+                o = cursor.getObject();

+            }

+            if (!(o instanceof CTTbl)) {

+                tables.add(0, newT);

+            } else {

+                int pos = tables.indexOf(getTable((CTTbl) o)) + 1;

+                tables.add(pos, newT);

+            }

+            int i = 0;

+            cursor = t.newCursor();

+            while (cursor.toPrevSibling()) {

+                o = cursor.getObject();

+                if (o instanceof CTP || o instanceof CTTbl)

+                    i++;

+            }

+            bodyElements.add(i, newT);

             cursor = t.newCursor();
             cursor.toEndToken();
             return newT;
         }
         return null;
     }
-
-    /**
-     * add a new paragraph at position of the cursor
-     * @param cursor
-     * @return the inserted paragraph
-     * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor)
-     */
-    public XWPFParagraph insertNewParagraph(XmlCursor cursor){
-        if(isCursorInFtn(cursor)){
-            String uri = CTP.type.getName().getNamespaceURI();
-            String localPart = "p";
-            cursor.beginElement(localPart,uri);
-            cursor.toParent();
-            CTP p = (CTP)cursor.getObject();
-            XWPFParagraph newP = new XWPFParagraph(p, this);
-            XmlObject o = null;
-            while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
-                o = cursor.getObject();
-            }
-            if((!(o instanceof CTP)) || (CTP)o == p){
-                paragraphs.add(0, newP);
-            }
-            else{
-                int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
-                paragraphs.add(pos,newP);
-            }
-            int i=0;
-            cursor.toCursor(p.newCursor());
-            while(cursor.toPrevSibling()){
-                o =cursor.getObject();
-                if(o instanceof CTP || o instanceof CTTbl)
-                    i++;
-            }
-            bodyElements.add(i, newP);
+

+    /**

+     * add a new paragraph at position of the cursor

+     *

+     * @param cursor

+     * @return the inserted paragraph

+     * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor)

+     */

+    public XWPFParagraph insertNewParagraph(XmlCursor cursor) {

+        if (isCursorInFtn(cursor)) {

+            String uri = CTP.type.getName().getNamespaceURI();

+            String localPart = "p";

+            cursor.beginElement(localPart, uri);

+            cursor.toParent();

+            CTP p = (CTP) cursor.getObject();

+            XWPFParagraph newP = new XWPFParagraph(p, this);

+            XmlObject o = null;

+            while (!(o instanceof CTP) && (cursor.toPrevSibling())) {

+                o = cursor.getObject();

+            }

+            if ((!(o instanceof CTP)) || (CTP) o == p) {

+                paragraphs.add(0, newP);

+            } else {

+                int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;

+                paragraphs.add(pos, newP);

+            }

+            int i = 0;

+            cursor.toCursor(p.newCursor());

+            while (cursor.toPrevSibling()) {

+                o = cursor.getObject();

+                if (o instanceof CTP || o instanceof CTTbl)

+                    i++;

+            }

+            bodyElements.add(i, newP);

             cursor.toCursor(p.newCursor());
             cursor.toEndToken();
             return newP;
         }
         return null;
     }
-
-    /**
-     * add a new table to the end of the footnote
-     * @param table
-     * @return the added XWPFTable
-     */
+

+    /**

+     * add a new table to the end of the footnote

+     *

+     * @param table

+     * @return the added XWPFTable

+     */

     public XWPFTable addNewTbl(CTTbl table) {
         CTTbl newTable = ctFtnEdn.addNewTbl();
         newTable.set(table);
@@ -322,12 +327,13 @@
         tables.add(xTable);
         return xTable;
     }
-
-    /**
-     * add a new paragraph to the end of the footnote
-     * @param paragraph
-     * @return the added XWPFParagraph
-     */
+

+    /**

+     * add a new paragraph to the end of the footnote

+     *

+     * @param paragraph

+     * @return the added XWPFParagraph

+     */

     public XWPFParagraph addNewParagraph(CTP paragraph) {
         CTP newPara = ctFtnEdn.addNewP();
         newPara.set(paragraph);
@@ -336,26 +342,28 @@
         return xPara;
     }
 
-    /**
-     * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument()
-     */
-    public  XWPFDocument getXWPFDocument() {
-        return document;
-    }
-
-    /**
-     * returns the Part, to which the body belongs, which you need for adding relationship to other parts
-     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
-     */
-    public POIXMLDocumentPart getPart() {
+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument()

+     */

+    public XWPFDocument getXWPFDocument() {

+        return document;

+    }

+

+    /**

+     * returns the Part, to which the body belongs, which you need for adding relationship to other parts

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()

+     */

+    public POIXMLDocumentPart getPart() {

         return footnotes;
     }
-
-    /**
-     * get the PartType of the body
-     * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
-     */
-    public BodyType getPartType() {
+

+    /**

+     * get the PartType of the body

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()

+     */

+    public BodyType getPartType() {

         return BodyType.FOOTNOTE;
     }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java
index 8647454..c84cab6 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java
@@ -31,32 +31,31 @@
 import org.apache.poi.POIXMLException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.openxml4j.opc.PackageRelationship;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFootnotes;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument;
-
-/**
- * Looks after the collection of Footnotes for a document
- */
-public class XWPFFootnotes extends POIXMLDocumentPart {
-    private List<XWPFFootnote> listFootnote = new ArrayList<XWPFFootnote>();
-    private CTFootnotes ctFootnotes;
-
-    protected XWPFDocument document;
-
-    /**
-     * Construct XWPFFootnotes from a package part
-     *
-     * @param part the package part holding the data of the footnotes,
-     * @param rel  the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"
-     */
-    public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
-        super(part, rel);
-    }
-
+import org.apache.poi.openxml4j.opc.PackageRelationship;

+import org.apache.xmlbeans.XmlException;

+import org.apache.xmlbeans.XmlOptions;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFootnotes;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument;

+

+/**

+ * Looks after the collection of Footnotes for a document

+ */

+public class XWPFFootnotes extends POIXMLDocumentPart {

+    protected XWPFDocument document;

+    private List<XWPFFootnote> listFootnote = new ArrayList<XWPFFootnote>();

+    private CTFootnotes ctFootnotes;

+

+    /**

+     * Construct XWPFFootnotes from a package part

+     *

+     * @param part the package part holding the data of the footnotes,

+     * @param rel  the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"

+     */

+    public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException {

+        super(part, rel);

+    }

+

     /**
      * Construct XWPFFootnotes from scratch for a new document.
      */
@@ -65,33 +64,33 @@
 
     /**
      * Read document
-     */
-    @Override
-    @SuppressWarnings("deprecation")
-    protected void onDocumentRead () throws IOException {
-        FootnotesDocument notesDoc;
-        try {
-            InputStream is = getPackagePart().getInputStream();
+     */

+    @Override

+    @SuppressWarnings("deprecation")

+    protected void onDocumentRead() throws IOException {

+        FootnotesDocument notesDoc;

+        try {

+            InputStream is = getPackagePart().getInputStream();

             notesDoc = FootnotesDocument.Factory.parse(is);
             ctFootnotes = notesDoc.getFootnotes();
         } catch (XmlException e) {
             throw new POIXMLException();
-        }
-
-        // Find our footnotes
-        for(CTFtnEdn note : ctFootnotes.getFootnoteArray()) {
-            listFootnote.add(new XWPFFootnote(note, this));
-        }
-    }
+        }

+

+        // Find our footnotes

+        for (CTFtnEdn note : ctFootnotes.getFootnoteArray()) {

+            listFootnote.add(new XWPFFootnote(note, this));

+        }

+    }

 
     @Override
-    protected void commit() throws IOException {
-        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTFootnotes.type.getName().getNamespaceURI(), "footnotes"));
-        Map<String,String> map = new HashMap<String,String>();
-        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
-        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
-        xmlOptions.setSaveSuggestedPrefixes(map);
+    protected void commit() throws IOException {

+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);

+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTFootnotes.type.getName().getNamespaceURI(), "footnotes"));

+        Map<String, String> map = new HashMap<String, String>();

+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");

+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");

+        xmlOptions.setSaveSuggestedPrefixes(map);

         PackagePart part = getPackagePart();
         OutputStream out = part.getOutputStream();
         ctFootnotes.save(out, xmlOptions);
@@ -100,59 +99,62 @@
 
     public List<XWPFFootnote> getFootnotesList() {
         return listFootnote;
+    }

+

+    public XWPFFootnote getFootnoteById(int id) {

+        for (XWPFFootnote note : listFootnote) {

+            if (note.getCTFtnEdn().getId().intValue() == id)

+                return note;

+        }

+        return null;

     }
-
-    public XWPFFootnote getFootnoteById(int id) {
-        for(XWPFFootnote note : listFootnote) {
-            if(note.getCTFtnEdn().getId().intValue() == id)
-                return note;
-        }
-        return null;
-    }
-
-    /**
-     * Sets the ctFootnotes
-     * @param footnotes
-     */
-    public void setFootnotes(CTFootnotes footnotes) {
+

+    /**

+     * Sets the ctFootnotes

+     *

+     * @param footnotes

+     */

+    public void setFootnotes(CTFootnotes footnotes) {

         ctFootnotes = footnotes;
     }
-
-    /**
-     * add an XWPFFootnote to the document
-     * @param footnote
-     * @throws IOException		 
-     */
-    public void addFootnote(XWPFFootnote footnote){
-        listFootnote.add(footnote);
-        ctFootnotes.addNewFootnote().set(footnote.getCTFtnEdn());
-    }
-
-    /**
-     * add a footnote to the document
-     * @param note
-     * @throws IOException		 
-     */
-    public XWPFFootnote addFootnote(CTFtnEdn note){
-        CTFtnEdn newNote = ctFootnotes.addNewFootnote();
-        newNote.set(note);
-        XWPFFootnote xNote = new XWPFFootnote(newNote, this);
+

+    /**

+     * add an XWPFFootnote to the document

+     *

+     * @param footnote

+     * @throws IOException

+     */

+    public void addFootnote(XWPFFootnote footnote) {

+        listFootnote.add(footnote);

+        ctFootnotes.addNewFootnote().set(footnote.getCTFtnEdn());

+    }

+

+    /**

+     * add a footnote to the document

+     *

+     * @param note

+     * @throws IOException

+     */

+    public XWPFFootnote addFootnote(CTFtnEdn note) {

+        CTFtnEdn newNote = ctFootnotes.addNewFootnote();

+        newNote.set(note);

+        XWPFFootnote xNote = new XWPFFootnote(newNote, this);

         listFootnote.add(xNote);
-        return xNote;
-    }
-
-    public void setXWPFDocument(XWPFDocument doc) {
-        document = doc;
-    }
-
-    /**
-     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
-     */
-    public XWPFDocument getXWPFDocument() {
-        if ( document != null) {
-            return document;
-        } else {
-            return (XWPFDocument)getParent();
-        }
-    }
-}
+        return xNote;

+    }

+

+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()

+     */

+    public XWPFDocument getXWPFDocument() {

+        if (document != null) {

+            return document;

+        } else {

+            return (XWPFDocument) getParent();

+        }

+    }

+

+    public void setXWPFDocument(XWPFDocument doc) {

+        document = doc;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
index a07bf41..2a31247 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
@@ -69,14 +69,14 @@
         cursor.dispose();
     }
 
-	/**
+    /**
      * save and commit footer
      */
     @Override
     protected void commit() throws IOException {
         XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
         xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "hdr"));
-        Map<String,String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<String, String>();
         map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
         map.put("urn:schemas-microsoft-com:office:office", "o");
         map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
@@ -95,11 +95,12 @@
 
     /**
      * reads the document
-     * @throws IOException 
+     *
+     * @throws IOException
      */
-    @Override  
+    @Override
     protected void onDocumentRead() throws IOException {
-        super.onDocumentRead();	          
+        super.onDocumentRead();
         HdrDocument hdrDocument = null;
         InputStream is;
         try {
@@ -113,17 +114,17 @@
             while (cursor.toNextSelection()) {
                 XmlObject o = cursor.getObject();
                 if (o instanceof CTP) {
-                    XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                    XWPFParagraph p = new XWPFParagraph((CTP) o, this);
                     paragraphs.add(p);
                     bodyElements.add(p);
                 }
                 if (o instanceof CTTbl) {
-                    XWPFTable t = new XWPFTable((CTTbl)o, this);
+                    XWPFTable t = new XWPFTable((CTTbl) o, this);
                     tables.add(t);
                     bodyElements.add(t);
                 }
-                if (o instanceof CTSdtBlock){
-                    XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
+                if (o instanceof CTSdtBlock) {
+                    XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this);
                     bodyElements.add(c);
                 }
             }
@@ -135,6 +136,7 @@
 
     /**
      * get the PartType of the body
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
      */
     public BodyType getPartType() {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
index e6dee2f..2f96a68 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
@@ -46,7 +46,7 @@
  */
 public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody {
     List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>(1);
-    List<XWPFTable> tables= new ArrayList<XWPFTable>(1);
+    List<XWPFTable> tables = new ArrayList<XWPFTable>(1);
     List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
     List<IBodyElement> bodyElements = new ArrayList<IBodyElement>(1);
 
@@ -54,7 +54,7 @@
     XWPFDocument document;
 
     XWPFHeaderFooter(XWPFDocument doc, CTHdrFtr hdrFtr) {
-        if (doc==null) {
+        if (doc == null) {
             throw new NullPointerException();
         }
 
@@ -70,17 +70,17 @@
 
     public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
         super(parent, part, rel);
-        this.document = (XWPFDocument)getParent();
+        this.document = (XWPFDocument) getParent();
 
-        if (this.document==null) {
+        if (this.document == null) {
             throw new NullPointerException();
         }
     }
 
     @Override
     protected void onDocumentRead() throws IOException {
-        for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
-            if(poixmlDocumentPart instanceof XWPFPictureData){
+        for (POIXMLDocumentPart poixmlDocumentPart : getRelations()) {
+            if (poixmlDocumentPart instanceof XWPFPictureData) {
                 XWPFPictureData xwpfPicData = (XWPFPictureData) poixmlDocumentPart;
                 pictures.add(xwpfPicData);
                 document.registerPackagePictureData(xwpfPicData);
@@ -93,16 +93,16 @@
         return headerFooter;
     }
 
-    public List<IBodyElement> getBodyElements(){
+    public List<IBodyElement> getBodyElements() {
         return Collections.unmodifiableList(bodyElements);
     }
 
     /**
      * Returns the paragraph(s) that holds
-     *  the text of the header or footer.
+     * the text of the header or footer.
      * Normally there is only the one paragraph, but
-     *  there could be more in certain cases, or 
-     *  a table.
+     * there could be more in certain cases, or
+     * a table.
      */
     public List<XWPFParagraph> getParagraphs() {
         return Collections.unmodifiableList(paragraphs);
@@ -111,29 +111,28 @@
 
     /**
      * Return the table(s) that holds the text
-     *  of the header or footer, for complex cases
-     *  where a paragraph isn't used.
+     * of the header or footer, for complex cases
+     * where a paragraph isn't used.
      * Normally there's just one paragraph, but some
-     *  complex headers/footers have a table or two
-     *  in addition. 
+     * complex headers/footers have a table or two
+     * in addition.
      */
-    public List<XWPFTable> getTables()throws ArrayIndexOutOfBoundsException {
+    public List<XWPFTable> getTables() throws ArrayIndexOutOfBoundsException {
         return Collections.unmodifiableList(tables);
     }
 
 
-
     /**
      * Returns the textual content of the header/footer,
-     *  by flattening out the text of its paragraph(s)
+     * by flattening out the text of its paragraph(s)
      */
     public String getText() {
         StringBuffer t = new StringBuffer();
-      //TODO: simplify this to get ibody elements in order
-        for(int i=0; i<paragraphs.size(); i++) {
-            if(! paragraphs.get(i).isEmpty()) {
+        //TODO: simplify this to get ibody elements in order
+        for (int i = 0; i < paragraphs.size(); i++) {
+            if (!paragraphs.get(i).isEmpty()) {
                 String text = paragraphs.get(i).getText();
-                if(text != null && text.length() > 0) {
+                if (text != null && text.length() > 0) {
                     t.append(text);
                     t.append('\n');
                 }
@@ -141,26 +140,26 @@
         }
 
         List<XWPFTable> tables = getTables();
-        for(int i=0; i<tables.size(); i++) {
+        for (int i = 0; i < tables.size(); i++) {
             String text = tables.get(i).getText();
-            if(text != null && text.length() > 0) {
+            if (text != null && text.length() > 0) {
                 t.append(text);
                 t.append('\n');
             }
         }
-        
-        for (IBodyElement bodyElement : getBodyElements()){
-           if (bodyElement instanceof XWPFSDT){
-               t.append(((XWPFSDT) bodyElement).getContent().getText()+'\n');
-           }
-       }
-        return t.toString(); 
+
+        for (IBodyElement bodyElement : getBodyElements()) {
+            if (bodyElement instanceof XWPFSDT) {
+                t.append(((XWPFSDT) bodyElement).getContent().getText() + '\n');
+            }
+        }
+        return t.toString();
     }
 
     /**
      * set a new headerFooter
      */
-    public void setHeaderFooter(CTHdrFtr headerFooter){
+    public void setHeaderFooter(CTHdrFtr headerFooter) {
         this.headerFooter = headerFooter;
         readHdrFtr();
     }
@@ -168,14 +167,15 @@
     /**
      * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header
      * the method will return this table
-     * if there is no corresponding {@link XWPFTable} the method will return null 
+     * if there is no corresponding {@link XWPFTable} the method will return null
+     *
      * @param ctTable
      */
-    public XWPFTable getTable(CTTbl ctTable){
+    public XWPFTable getTable(CTTbl ctTable) {
         for (XWPFTable table : tables) {
-            if(table==null)
+            if (table == null)
                 return null;
-            if(table.getCTTbl().equals(ctTable))
+            if (table.getCTTbl().equals(ctTable))
                 return table;
         }
         return null;
@@ -184,14 +184,15 @@
     /**
      * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer
      * the method will return this paragraph
-     * if there is no corresponding {@link XWPFParagraph} the method will return null 
+     * if there is no corresponding {@link XWPFParagraph} the method will return null
+     *
      * @param p is instance of CTP and is searching for an XWPFParagraph
      * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer
-     * 		   XWPFParagraph with the correspondig CTP p
+     * XWPFParagraph with the correspondig CTP p
      */
-    public XWPFParagraph getParagraph(CTP p){
+    public XWPFParagraph getParagraph(CTP p) {
         for (XWPFParagraph paragraph : paragraphs) {
-            if(paragraph.getCTP().equals(p))
+            if (paragraph.getCTP().equals(p))
                 return paragraph;
         }
         return null;
@@ -200,7 +201,7 @@
 
     /**
      * Returns the paragraph that holds
-     *  the text of the header or footer.
+     * the text of the header or footer.
      */
     public XWPFParagraph getParagraphArray(int pos) {
 
@@ -209,9 +210,10 @@
 
     /**
      * get a List of all Paragraphs
-     * @return a list of {@link XWPFParagraph} 
+     *
+     * @return a list of {@link XWPFParagraph}
      */
-    public List<XWPFParagraph> getListParagraph(){
+    public List<XWPFParagraph> getListParagraph() {
         return paragraphs;
     }
 
@@ -221,9 +223,10 @@
 
     /**
      * get all Pictures in this package
+     *
      * @return all Pictures in this package
      */
-    public List<XWPFPictureData> getAllPackagePictures(){
+    public List<XWPFPictureData> getAllPackagePictures() {
         return document.getAllPackagePictures();
 
     }
@@ -231,22 +234,19 @@
     /**
      * Adds a picture to the document.
      *
-     * @param pictureData       The picture data
-     * @param format            The format of the picture.
-     *
+     * @param pictureData The picture data
+     * @param format      The format of the picture.
      * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
-     * @throws InvalidFormatException 
+     * @throws InvalidFormatException
      */
-    public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
-    {
+    public String addPictureData(byte[] pictureData, int format) throws InvalidFormatException {
         XWPFPictureData xwpfPicData = document.findPackagePictureData(pictureData, format);
         POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
 
-        if (xwpfPicData == null)
-        {
+        if (xwpfPicData == null) {
             /* Part doesn't exist, create a new one */
             int idx = document.getNextPicNameNumber(format);
-            xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
+            xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(), idx);
             /* write bytes to new part */
             PackagePart picDataPart = xwpfPicData.getPackagePart();
             OutputStream out = null;
@@ -266,9 +266,7 @@
             document.registerPackagePictureData(xwpfPicData);
             pictures.add(xwpfPicData);
             return getRelationId(xwpfPicData);
-        }
-        else if (!getRelations().contains(xwpfPicData))
-        {
+        } else if (!getRelations().contains(xwpfPicData)) {
             /*
              * Part already existed, but was not related so far. Create
              * relationship to the already existing part and update
@@ -279,14 +277,12 @@
             TargetMode targetMode = TargetMode.INTERNAL;
             PackagePartName partName = picDataPart.getPartName();
             String relation = relDesc.getRelation();
-            PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
+            PackageRelationship relShip = getPackagePart().addRelationship(partName, targetMode, relation);
             String id = relShip.getId();
-            addRelation(id,xwpfPicData);
+            addRelation(id, xwpfPicData);
             pictures.add(xwpfPicData);
             return id;
-        }
-        else 
-        {
+        } else {
             /* Part already existed, get relation id and return it */
             return getRelationId(xwpfPicData);
         }
@@ -295,61 +291,61 @@
     /**
      * Adds a picture to the document.
      *
-     * @param is                The stream to read image from
-     * @param format            The format of the picture.
-     *
+     * @param is     The stream to read image from
+     * @param format The format of the picture.
      * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
-     * @throws InvalidFormatException 
-     * @throws IOException 
+     * @throws InvalidFormatException
+     * @throws IOException
      */
-    public String addPictureData(InputStream is, int format) throws InvalidFormatException,IOException {
+    public String addPictureData(InputStream is, int format) throws InvalidFormatException, IOException {
         byte[] data = IOUtils.toByteArray(is);
-        return addPictureData(data,format);
+        return addPictureData(data, format);
     }
 
     /**
      * returns the PictureData by blipID
+     *
      * @param blipID
      * @return XWPFPictureData of a specificID
-     * @throws Exception 
+     * @throws Exception
      */
     public XWPFPictureData getPictureDataByID(String blipID) {
         POIXMLDocumentPart relatedPart = getRelationById(blipID);
         if (relatedPart != null && relatedPart instanceof XWPFPictureData) {
             return (XWPFPictureData) relatedPart;
         }
-        return null;   
+        return null;
     }
 
     /**
      * add a new paragraph at position of the cursor
+     *
      * @param cursor
      * @return the inserted paragraph
      */
-    public XWPFParagraph insertNewParagraph(XmlCursor cursor){
-        if(isCursorInHdrF(cursor)){
+    public XWPFParagraph insertNewParagraph(XmlCursor cursor) {
+        if (isCursorInHdrF(cursor)) {
             String uri = CTP.type.getName().getNamespaceURI();
             String localPart = "p";
-            cursor.beginElement(localPart,uri);
+            cursor.beginElement(localPart, uri);
             cursor.toParent();
-            CTP p = (CTP)cursor.getObject();
+            CTP p = (CTP) cursor.getObject();
             XWPFParagraph newP = new XWPFParagraph(p, this);
             XmlObject o = null;
-            while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
+            while (!(o instanceof CTP) && (cursor.toPrevSibling())) {
                 o = cursor.getObject();
             }
-            if((!(o instanceof CTP)) || (CTP)o == p){
+            if ((!(o instanceof CTP)) || (CTP) o == p) {
                 paragraphs.add(0, newP);
+            } else {
+                int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;
+                paragraphs.add(pos, newP);
             }
-            else{
-                int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
-                paragraphs.add(pos,newP);
-            }
-            int i=0;
+            int i = 0;
             cursor.toCursor(p.newCursor());
-            while(cursor.toPrevSibling()){
-                o =cursor.getObject();
-                if(o instanceof CTP || o instanceof CTTbl)
+            while (cursor.toPrevSibling()) {
+                o = cursor.getObject();
+                if (o instanceof CTP || o instanceof CTTbl)
                     i++;
             }
             bodyElements.add(i, newP);
@@ -362,35 +358,33 @@
 
 
     /**
-     * 
      * @param cursor
      * @return the inserted table
      */
     public XWPFTable insertNewTbl(XmlCursor cursor) {
-        if(isCursorInHdrF(cursor)){
+        if (isCursorInHdrF(cursor)) {
             String uri = CTTbl.type.getName().getNamespaceURI();
             String localPart = "tbl";
-            cursor.beginElement(localPart,uri);
+            cursor.beginElement(localPart, uri);
             cursor.toParent();
-            CTTbl t = (CTTbl)cursor.getObject();
+            CTTbl t = (CTTbl) cursor.getObject();
             XWPFTable newT = new XWPFTable(t, this);
             cursor.removeXmlContents();
             XmlObject o = null;
-            while(!(o instanceof CTTbl)&&(cursor.toPrevSibling())){
+            while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) {
                 o = cursor.getObject();
             }
-            if(!(o instanceof CTTbl)){
+            if (!(o instanceof CTTbl)) {
                 tables.add(0, newT);
+            } else {
+                int pos = tables.indexOf(getTable((CTTbl) o)) + 1;
+                tables.add(pos, newT);
             }
-            else{
-                int pos = tables.indexOf(getTable((CTTbl)o))+1;
-                tables.add(pos,newT);
-            }
-            int i=0;
+            int i = 0;
             cursor = t.newCursor();
-            while(cursor.toPrevSibling()){
-                o =cursor.getObject();
-                if(o instanceof CTP || o instanceof CTTbl)
+            while (cursor.toPrevSibling()) {
+                o = cursor.getObject();
+                if (o instanceof CTP || o instanceof CTTbl)
                     i++;
             }
             bodyElements.add(i, newT);
@@ -403,29 +397,31 @@
 
     /**
      * verifies that cursor is on the right position
+     *
      * @param cursor
      */
     private boolean isCursorInHdrF(XmlCursor cursor) {
         XmlCursor verify = cursor.newCursor();
         verify.toParent();
-        if(verify.getObject() == this.headerFooter){
+        if (verify.getObject() == this.headerFooter) {
             return true;
         }
         return false;
     }
 
 
-    public POIXMLDocumentPart getOwner(){
+    public POIXMLDocumentPart getOwner() {
         return this;
     }
 
     /**
      * Returns the table at position pos
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
      */
     public XWPFTable getTableArray(int pos) {
 
-        if(pos > 0 && pos < tables.size()){
+        if (pos > 0 && pos < tables.size()) {
             return tables.get(pos);
         }
         return null;
@@ -433,6 +429,7 @@
 
     /**
      * inserts an existing XWPFTable to the arrays bodyElements and tables
+     *
      * @param pos
      * @param table
      */
@@ -441,7 +438,7 @@
         bodyElements.add(pos, table);
         int i = 0;
         for (CTTbl tbl : headerFooter.getTblArray()) {
-            if(tbl == table.getCTTbl()){
+            if (tbl == table.getCTTbl()) {
                 break;
             }
             i++;
@@ -450,10 +447,10 @@
 
     }
 
-    public void readHdrFtr(){
+    public void readHdrFtr() {
         bodyElements = new ArrayList<IBodyElement>();
         paragraphs = new ArrayList<XWPFParagraph>();
-        tables= new ArrayList<XWPFTable>();
+        tables = new ArrayList<XWPFTable>();
         // parse the document with cursor and add
         // the XmlObject to its lists
         XmlCursor cursor = headerFooter.newCursor();
@@ -461,12 +458,12 @@
         while (cursor.toNextSelection()) {
             XmlObject o = cursor.getObject();
             if (o instanceof CTP) {
-                XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                XWPFParagraph p = new XWPFParagraph((CTP) o, this);
                 paragraphs.add(p);
                 bodyElements.add(p);
             }
             if (o instanceof CTTbl) {
-                XWPFTable t = new XWPFTable((CTTbl)o, this);
+                XWPFTable t = new XWPFTable((CTTbl) o, this);
                 tables.add(t);
                 bodyElements.add(t);
             }
@@ -476,48 +473,50 @@
 
     /**
      * get the TableCell which belongs to the TableCell
+     *
      * @param cell
      */
     public XWPFTableCell getTableCell(CTTc cell) {
         XmlCursor cursor = cell.newCursor();
         cursor.toParent();
         XmlObject o = cursor.getObject();
-        if(!(o instanceof CTRow)){
+        if (!(o instanceof CTRow)) {
             return null;
         }
-        CTRow row = (CTRow)o;
+        CTRow row = (CTRow) o;
         cursor.toParent();
         o = cursor.getObject();
         cursor.dispose();
-        if(! (o instanceof CTTbl)){
+        if (!(o instanceof CTTbl)) {
             return null;
         }
         CTTbl tbl = (CTTbl) o;
         XWPFTable table = getTable(tbl);
-        if(table == null){
+        if (table == null) {
             return null;
         }
         XWPFTableRow tableRow = table.getRow(row);
-        if(row == null){
+        if (row == null) {
             return null;
         }
         return tableRow.getTableCell(cell);
     }
 
+    public XWPFDocument getXWPFDocument() {
+        if (document != null) {
+            return document;
+        } else {
+            return (XWPFDocument) getParent();
+        }
+    }
+
     public void setXWPFDocument(XWPFDocument doc) {
         document = doc;
     }
 
-    public XWPFDocument getXWPFDocument() {
-        if (document!=null) {
-            return document;
-        } else {
-            return (XWPFDocument)getParent();
-        }
-    }
-
     /**
      * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
      */
     public POIXMLDocumentPart getPart() {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java
index f9f2f9d..c00f75a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlink.java
@@ -18,26 +18,22 @@
 
 /**
  * Sketch of XWPF hyperlink class
- * 
-* @author Yury Batrakov (batrakov at gmail.com)
- * 
+ *
+ * @author Yury Batrakov (batrakov at gmail.com)
  */
-public class XWPFHyperlink
-{
+public class XWPFHyperlink {
     String id, url;
-    public XWPFHyperlink(String id, String url)
-    {
+
+    public XWPFHyperlink(String id, String url) {
         this.id = id;
         this.url = url;
     }
-    
-    public String getId()
-    {
+
+    public String getId() {
         return id;
     }
-    
-    public String getURL()
-    {
+
+    public String getURL() {
         return url;
     }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java
index 2461d33..4c8158a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHyperlinkRun.java
@@ -20,45 +20,45 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
 
 /**
- * A run of text with a Hyperlink applied to it.
- * Any given Hyperlink may be made up of multiple of these.
- */
-public class XWPFHyperlinkRun extends XWPFRun
-{
-   private CTHyperlink hyperlink;
-   
-   public XWPFHyperlinkRun(CTHyperlink hyperlink, CTR run, IRunBody p) {
-      super(run, p);
-      this.hyperlink = hyperlink;
-   }
-   
-   public CTHyperlink getCTHyperlink() {
-      return hyperlink;
-   }
-   
-   public String getAnchor() {
-      return hyperlink.getAnchor();
-   }
-   
-   /**
-    * Returns the ID of the hyperlink, if one is set.
-    */
-   public String getHyperlinkId() {
-      return hyperlink.getId();
-   }
-   public void setHyperlinkId(String id) {
-      hyperlink.setId(id);
-   }
-   
-   /**
-    * If this Hyperlink is an external reference hyperlink,
-    *  return the object for it.
-    */
-   public XWPFHyperlink getHyperlink(XWPFDocument document) {
-      String id = getHyperlinkId();
-      if(id == null)
-         return null;
-      
-      return document.getHyperlinkByID(id);
-   }
-}
+ * A run of text with a Hyperlink applied to it.

+ * Any given Hyperlink may be made up of multiple of these.

+ */

+public class XWPFHyperlinkRun extends XWPFRun {

+    private CTHyperlink hyperlink;

+

+    public XWPFHyperlinkRun(CTHyperlink hyperlink, CTR run, IRunBody p) {

+        super(run, p);

+        this.hyperlink = hyperlink;

+    }

+

+    public CTHyperlink getCTHyperlink() {

+        return hyperlink;

+    }

+

+    public String getAnchor() {

+        return hyperlink.getAnchor();

+    }

+

+    /**

+     * Returns the ID of the hyperlink, if one is set.

+     */

+    public String getHyperlinkId() {

+        return hyperlink.getId();

+    }

+

+    public void setHyperlinkId(String id) {

+        hyperlink.setId(id);

+    }

+

+    /**

+     * If this Hyperlink is an external reference hyperlink,

+     * return the object for it.

+     */

+    public XWPFHyperlink getHyperlink(XWPFDocument document) {

+        String id = getHyperlinkId();

+        if (id == null)

+            return null;

+

+        return document.getHyperlinkByID(id);

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
index 83b898c..ab802ff 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
@@ -17,34 +17,38 @@
 package org.apache.poi.xwpf.usermodel;
 
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;

+

+public class XWPFLatentStyles {

+    protected XWPFStyles styles; //LatentStyle shall know styles

+    private CTLatentStyles latentStyles;

+

+    protected XWPFLatentStyles() {

+    }

+

+    protected XWPFLatentStyles(CTLatentStyles latentStyles) {

+        this(latentStyles, null);

+    }

+

+    protected XWPFLatentStyles(CTLatentStyles latentStyles, XWPFStyles styles) {

+        this.latentStyles = latentStyles;

+        this.styles = styles;

+    }

+

+    public int getNumberOfStyles() {

+        return latentStyles.sizeOfLsdExceptionArray();
+    }
 
-public class XWPFLatentStyles {
-	private CTLatentStyles latentStyles;
-	protected XWPFStyles styles; //LatentStyle shall know styles
-	
-	protected XWPFLatentStyles(){
-	}
-	
-	protected XWPFLatentStyles(CTLatentStyles latentStyles){
-		this(latentStyles,null);
-	}
-	
-	protected XWPFLatentStyles(CTLatentStyles latentStyles, XWPFStyles styles) {
-		this.latentStyles=latentStyles;
-		this.styles=styles;
-	}
-	
-	/**
-	 * checks wheter specific LatentStyleID is a latentStyle
-	*/
-    @SuppressWarnings("deprecation")
-	protected boolean isLatentStyle(String latentStyleID){	
-		for ( CTLsdException lsd: latentStyles.getLsdExceptionArray()) {
-			if(lsd.getName().equals(latentStyleID)) {
-				return true;
-			}
-		}
-		return false;		
-	}
-}
+    /**
+     * checks whether specific LatentStyleID is a latentStyle

+     */

+    @SuppressWarnings("deprecation")

+    protected boolean isLatentStyle(String latentStyleID) {

+        for (CTLsdException lsd : latentStyles.getLsdExceptionArray()) {

+            if (lsd.getName().equals(latentStyleID)) {

+                return true;

+            }

+        }

+        return false;

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
index 300936d..b1ae7ed 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
@@ -18,48 +18,47 @@
 
 
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
-
-/**
- * @author Philipp Epp
- *
- */
-public class XWPFNum {
-	private CTNum ctNum;
-	protected XWPFNumbering numbering;
-	
-	public XWPFNum(){
-		this.ctNum = null;
-		this.numbering = null;
-	}
-	
-	public XWPFNum(CTNum ctNum){
-		this.ctNum = ctNum;
-		this.numbering = null;
-	}
-	
-	public XWPFNum(XWPFNumbering numbering){
-		this.ctNum = null;
-		this.numbering = numbering;
-	}
-	
-	public XWPFNum(CTNum ctNum, XWPFNumbering numbering){
-		this.ctNum = ctNum;
-		this.numbering = numbering;
-	}
-	
-	public XWPFNumbering getNumbering(){
-		return numbering;
-	}
-	
-	public CTNum getCTNum(){
-		return ctNum;
-	}
-	
-	public void setNumbering(XWPFNumbering numbering){
-		this.numbering = numbering;
-	}
-	
-	public void setCTNum(CTNum ctNum){
-		this.ctNum = ctNum;
-	}
+

+/**

+ * @author Philipp Epp

+ */

+public class XWPFNum {

+    protected XWPFNumbering numbering;

+    private CTNum ctNum;

+

+    public XWPFNum() {

+        this.ctNum = null;

+        this.numbering = null;

+    }

+

+    public XWPFNum(CTNum ctNum) {

+        this.ctNum = ctNum;

+        this.numbering = null;

+    }

+

+    public XWPFNum(XWPFNumbering numbering) {

+        this.ctNum = null;

+        this.numbering = numbering;

+    }

+

+    public XWPFNum(CTNum ctNum, XWPFNumbering numbering) {

+        this.ctNum = ctNum;

+        this.numbering = numbering;

+    }

+

+    public XWPFNumbering getNumbering() {

+        return numbering;

+    }

+

+    public void setNumbering(XWPFNumbering numbering) {

+        this.numbering = numbering;

+    }

+

+    public CTNum getCTNum() {

+        return ctNum;

+    }

+

+    public void setCTNum(CTNum ctNum) {

+        this.ctNum = ctNum;

+    }

 }
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
index 1bc8af5..842bb44 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
@@ -38,71 +38,69 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
-
-/**
- * @author Philipp Epp
- *
- */
-public class XWPFNumbering extends POIXMLDocumentPart {
-    protected List<XWPFAbstractNum> abstractNums = new ArrayList<XWPFAbstractNum>();
-    protected List<XWPFNum> nums = new ArrayList<XWPFNum>();
-
-    private CTNumbering ctNumbering;
-	boolean isNew;
-	
-	/**
-	 *create a new styles object with an existing document 
-	 */
-	public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
-		super(part, rel);
-		isNew = true;
-	}
-
-	/**
-	 * create a new XWPFNumbering object for use in a new document
-	 */
-	public XWPFNumbering(){
-		abstractNums = new ArrayList<XWPFAbstractNum>();
-		nums = new ArrayList<XWPFNum>();
-		isNew = true;
-	}
-
-	/**
-	 * read numbering form an existing package
-	 */
-	@Override
-    @SuppressWarnings("deprecation")
-	protected void onDocumentRead() throws IOException{
-		NumberingDocument numberingDoc = null;
-		InputStream is;
-		is = getPackagePart().getInputStream();
-		try {
-			numberingDoc = NumberingDocument.Factory.parse(is);
-			ctNumbering = numberingDoc.getNumbering();
-	        //get any Nums
-	        for(CTNum ctNum : ctNumbering.getNumArray()) {
-	            nums.add(new XWPFNum(ctNum, this));
-	        }
-	        for(CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()){
-	        	abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this));
-	        }
-	        isNew = false;
-		} catch (XmlException e) {
-			throw new POIXMLException();
-		}
-	}
-	
-	/**
-	 * save and commit numbering
-	 */
-	@Override
-    protected void commit() throws IOException {
-        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering"));
-        Map<String,String> map = new HashMap<String,String>();
-        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
-        map.put("urn:schemas-microsoft-com:office:office", "o");
-        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+

+/**

+ * @author Philipp Epp

+ */

+public class XWPFNumbering extends POIXMLDocumentPart {

+    protected List<XWPFAbstractNum> abstractNums = new ArrayList<XWPFAbstractNum>();

+    protected List<XWPFNum> nums = new ArrayList<XWPFNum>();

+    boolean isNew;

+    private CTNumbering ctNumbering;

+

+    /**

+     * create a new styles object with an existing document

+     */

+    public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException {

+        super(part, rel);

+        isNew = true;

+    }

+

+    /**

+     * create a new XWPFNumbering object for use in a new document

+     */

+    public XWPFNumbering() {

+        abstractNums = new ArrayList<XWPFAbstractNum>();

+        nums = new ArrayList<XWPFNum>();

+        isNew = true;

+    }

+

+    /**

+     * read numbering form an existing package

+     */

+    @Override

+    @SuppressWarnings("deprecation")

+    protected void onDocumentRead() throws IOException {

+        NumberingDocument numberingDoc = null;

+        InputStream is;

+        is = getPackagePart().getInputStream();

+        try {

+            numberingDoc = NumberingDocument.Factory.parse(is);

+            ctNumbering = numberingDoc.getNumbering();

+            //get any Nums

+            for (CTNum ctNum : ctNumbering.getNumArray()) {

+                nums.add(new XWPFNum(ctNum, this));

+            }

+            for (CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()) {

+                abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this));

+            }

+            isNew = false;

+        } catch (XmlException e) {

+            throw new POIXMLException();

+        }

+    }

+

+    /**

+     * save and commit numbering

+     */

+    @Override

+    protected void commit() throws IOException {

+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);

+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering"));

+        Map<String, String> map = new HashMap<String, String>();

+        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");

+        map.put("urn:schemas-microsoft-com:office:office", "o");

+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");

         map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
         map.put("urn:schemas-microsoft-com:vml", "v");
         map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
@@ -114,169 +112,182 @@
         OutputStream out = part.getOutputStream();
         ctNumbering.save(out, xmlOptions);
         out.close();
-    }
-
-
-	/**
-	 * Sets the ctNumbering
-	 * @param numbering
-	 */
-	public void setNumbering(CTNumbering numbering){
-		ctNumbering = numbering;
-	}
-	
-	
-	/**
-	 * Checks whether number with numID exists
-	 * @param numID
-	 * @return boolean		true if num exist, false if num not exist
-	 */
-	public boolean numExist(BigInteger numID){
-		for (XWPFNum num : nums) {
-			if (num.getCTNum().getNumId().equals(numID))
-				return true;
-		}
-		return false;
-	}
-	
-	/**
-	 * add a new number to the numbering document
-	 * @param num
-	 */
-	public BigInteger addNum(XWPFNum num){
-		ctNumbering.addNewNum();
-		int pos = ctNumbering.sizeOfNumArray() - 1;
-		ctNumbering.setNumArray(pos, num.getCTNum());
-		nums.add(num);
-		return num.getCTNum().getNumId();
-	}
-	
-	/**
-	 * Add a new num with an abstractNumID
-	 * @return return NumId of the added num 
-	 */
-	public BigInteger addNum(BigInteger abstractNumID){
-		CTNum ctNum = this.ctNumbering.addNewNum();
-		ctNum.addNewAbstractNumId();
-		ctNum.getAbstractNumId().setVal(abstractNumID);
-		ctNum.setNumId(BigInteger.valueOf(nums.size()+1));
-		XWPFNum num = new XWPFNum(ctNum, this);
-		nums.add(num);
-		return ctNum.getNumId();
-	}
-	
-	/**
-	 * Add a new num with an abstractNumID and a numID
-	 * @param abstractNumID
-	 * @param numID
-	 */
-	public void addNum(BigInteger abstractNumID, BigInteger numID){
-		CTNum ctNum = this.ctNumbering.addNewNum();
-		ctNum.addNewAbstractNumId();
-		ctNum.getAbstractNumId().setVal(abstractNumID);
-		ctNum.setNumId(numID);
-		XWPFNum num = new XWPFNum(ctNum, this);
-		nums.add(num);
-	}
-	
-	/**
-	 * get Num by NumID
-	 * @param numID
-	 * @return abstractNum with NumId if no Num exists with that NumID 
-	 * 			null will be returned
-	 */
-	public XWPFNum getNum(BigInteger numID){
-		for(XWPFNum num: nums){
-			if(num.getCTNum().getNumId().equals(numID))
-				return num;
-		}
-		return null;
-	}
-	/**
-	 * get AbstractNum by abstractNumID
-	 * @param abstractNumID
-	 * @return  abstractNum with abstractNumId if no abstractNum exists with that abstractNumID 
-	 * 			null will be returned
-	 */
-	public XWPFAbstractNum getAbstractNum(BigInteger abstractNumID){
-		for(XWPFAbstractNum abstractNum: abstractNums){
-			if(abstractNum.getAbstractNum().getAbstractNumId().equals(abstractNumID)){
-				return abstractNum;
-			}
-		}
-		return null;
-	}
-	/**
-	 * Compare AbstractNum with abstractNums of this numbering document.
-	 * If the content of abstractNum equals with an abstractNum of the List in numbering
-	 * the BigInteger Value of it will be returned.
-	 * If no equal abstractNum is existing null will be returned
-	 * 
-	 * @param abstractNum
-	 * @return 	BigInteger
-	 */
-	public BigInteger getIdOfAbstractNum(XWPFAbstractNum abstractNum){
-		CTAbstractNum copy = (CTAbstractNum) abstractNum.getCTAbstractNum().copy();
-		XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(copy, this);
-		int i;
-		for (i = 0; i < abstractNums.size(); i++) {
-			newAbstractNum.getCTAbstractNum().setAbstractNumId(BigInteger.valueOf(i));
-			newAbstractNum.setNumbering(this);
-			if(newAbstractNum.getCTAbstractNum().valueEquals(abstractNums.get(i).getCTAbstractNum())){
-				return newAbstractNum.getCTAbstractNum().getAbstractNumId();
-			}
-		}
-		return null;
-	}
-
-
-	/**
-	 * add a new AbstractNum and return its AbstractNumID 
-	 * @param abstractNum
-	 */
-	public BigInteger addAbstractNum(XWPFAbstractNum abstractNum){
-		int pos = abstractNums.size();
-		if(abstractNum.getAbstractNum() != null){ // Use the current CTAbstractNum if it exists
-			ctNumbering.addNewAbstractNum().set(abstractNum.getAbstractNum());
-		} else {
-			ctNumbering.addNewAbstractNum();
-			abstractNum.getAbstractNum().setAbstractNumId(BigInteger.valueOf(pos));
-			ctNumbering.setAbstractNumArray(pos, abstractNum.getAbstractNum());
-		}
-		abstractNums.add(abstractNum);
-		return abstractNum.getCTAbstractNum().getAbstractNumId();
-	}
-	
-	/**
-	 * remove an existing abstractNum 
-	 * @param abstractNumID
-	 * @return true if abstractNum with abstractNumID exists in NumberingArray,
-	 * 		   false if abstractNum with abstractNumID not exists
-	 */
-	public boolean removeAbstractNum(BigInteger abstractNumID){
-		if(abstractNumID.byteValue()<abstractNums.size()){
-			ctNumbering.removeAbstractNum(abstractNumID.byteValue());
-			abstractNums.remove(abstractNumID.byteValue());
-			return true;
-		}
-		return false;
-	}
-	/**
-	 *return the abstractNumID
-	 *If the AbstractNumID not exists
-	 *return null
-	 * @param 		numID
-	 * @return 		abstractNumID
-	 */
-	public BigInteger getAbstractNumID(BigInteger numID){
-		XWPFNum num = getNum(numID);
-		if(num == null)
-			return null;
-		if (num.getCTNum() == null)
-			return null;
-		if (num.getCTNum().getAbstractNumId() == null)
-			return null;
-		return num.getCTNum().getAbstractNumId().getVal();
-	}
-}
-	
+    }

+

+

+    /**

+     * Sets the ctNumbering

+     *

+     * @param numbering

+     */

+    public void setNumbering(CTNumbering numbering) {

+        ctNumbering = numbering;

+    }

+

+

+    /**

+     * Checks whether number with numID exists

+     *

+     * @param numID

+     * @return boolean        true if num exist, false if num not exist

+     */

+    public boolean numExist(BigInteger numID) {

+        for (XWPFNum num : nums) {

+            if (num.getCTNum().getNumId().equals(numID))

+                return true;

+        }

+        return false;

+    }

+

+    /**

+     * add a new number to the numbering document

+     *

+     * @param num

+     */

+    public BigInteger addNum(XWPFNum num) {

+        ctNumbering.addNewNum();

+        int pos = ctNumbering.sizeOfNumArray() - 1;

+        ctNumbering.setNumArray(pos, num.getCTNum());

+        nums.add(num);

+        return num.getCTNum().getNumId();

+    }

+

+    /**

+     * Add a new num with an abstractNumID

+     *

+     * @return return NumId of the added num

+     */

+    public BigInteger addNum(BigInteger abstractNumID) {

+        CTNum ctNum = this.ctNumbering.addNewNum();

+        ctNum.addNewAbstractNumId();

+        ctNum.getAbstractNumId().setVal(abstractNumID);

+        ctNum.setNumId(BigInteger.valueOf(nums.size() + 1));

+        XWPFNum num = new XWPFNum(ctNum, this);

+        nums.add(num);

+        return ctNum.getNumId();

+    }

+

+    /**

+     * Add a new num with an abstractNumID and a numID

+     *

+     * @param abstractNumID

+     * @param numID

+     */

+    public void addNum(BigInteger abstractNumID, BigInteger numID) {

+        CTNum ctNum = this.ctNumbering.addNewNum();

+        ctNum.addNewAbstractNumId();

+        ctNum.getAbstractNumId().setVal(abstractNumID);

+        ctNum.setNumId(numID);

+        XWPFNum num = new XWPFNum(ctNum, this);

+        nums.add(num);

+    }

+

+    /**

+     * get Num by NumID

+     *

+     * @param numID

+     * @return abstractNum with NumId if no Num exists with that NumID

+     * null will be returned

+     */

+    public XWPFNum getNum(BigInteger numID) {

+        for (XWPFNum num : nums) {

+            if (num.getCTNum().getNumId().equals(numID))

+                return num;

+        }

+        return null;

+    }

+

+    /**

+     * get AbstractNum by abstractNumID

+     *

+     * @param abstractNumID

+     * @return abstractNum with abstractNumId if no abstractNum exists with that abstractNumID

+     * null will be returned

+     */

+    public XWPFAbstractNum getAbstractNum(BigInteger abstractNumID) {

+        for (XWPFAbstractNum abstractNum : abstractNums) {

+            if (abstractNum.getAbstractNum().getAbstractNumId().equals(abstractNumID)) {

+                return abstractNum;

+            }

+        }

+        return null;

+    }

+

+    /**

+     * Compare AbstractNum with abstractNums of this numbering document.

+     * If the content of abstractNum equals with an abstractNum of the List in numbering

+     * the BigInteger Value of it will be returned.

+     * If no equal abstractNum is existing null will be returned

+     *

+     * @param abstractNum

+     * @return BigInteger

+     */

+    public BigInteger getIdOfAbstractNum(XWPFAbstractNum abstractNum) {

+        CTAbstractNum copy = (CTAbstractNum) abstractNum.getCTAbstractNum().copy();

+        XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(copy, this);

+        int i;

+        for (i = 0; i < abstractNums.size(); i++) {

+            newAbstractNum.getCTAbstractNum().setAbstractNumId(BigInteger.valueOf(i));

+            newAbstractNum.setNumbering(this);

+            if (newAbstractNum.getCTAbstractNum().valueEquals(abstractNums.get(i).getCTAbstractNum())) {

+                return newAbstractNum.getCTAbstractNum().getAbstractNumId();

+            }

+        }

+        return null;

+    }

+

+

+    /**

+     * add a new AbstractNum and return its AbstractNumID

+     *

+     * @param abstractNum

+     */

+    public BigInteger addAbstractNum(XWPFAbstractNum abstractNum) {

+        int pos = abstractNums.size();

+        if (abstractNum.getAbstractNum() != null) { // Use the current CTAbstractNum if it exists

+            ctNumbering.addNewAbstractNum().set(abstractNum.getAbstractNum());

+        } else {

+            ctNumbering.addNewAbstractNum();

+            abstractNum.getAbstractNum().setAbstractNumId(BigInteger.valueOf(pos));

+            ctNumbering.setAbstractNumArray(pos, abstractNum.getAbstractNum());

+        }

+        abstractNums.add(abstractNum);

+        return abstractNum.getCTAbstractNum().getAbstractNumId();

+    }

+

+    /**

+     * remove an existing abstractNum

+     *

+     * @param abstractNumID

+     * @return true if abstractNum with abstractNumID exists in NumberingArray,

+     * false if abstractNum with abstractNumID not exists

+     */

+    public boolean removeAbstractNum(BigInteger abstractNumID) {

+        if (abstractNumID.byteValue() < abstractNums.size()) {

+            ctNumbering.removeAbstractNum(abstractNumID.byteValue());

+            abstractNums.remove(abstractNumID.byteValue());

+            return true;

+        }

+        return false;

+    }

+

+    /**

+     * return the abstractNumID

+     * If the AbstractNumID not exists

+     * return null

+     *

+     * @param numID

+     * @return abstractNumID

+     */

+    public BigInteger getAbstractNumID(BigInteger numID) {

+        XWPFNum num = getNum(numID);

+        if (num == null)

+            return null;

+        if (num.getCTNum() == null)

+            return null;

+        if (num.getCTNum().getAbstractNumId() == null)

+            return null;

+        return num.getCTNum().getAbstractNumId().getVal();

+    }

+}

+

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
index 7ed629c..0eae922 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
@@ -28,11 +28,14 @@
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumLvl;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
@@ -56,16 +59,18 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
 
 /**
- * <p>A Paragraph within a Document, Table, Header etc.</p> 
- * 
+ * <p>A Paragraph within a Document, Table, Header etc.</p>
+ * <p/>
  * <p>A paragraph has a lot of styling information, but the
- *  actual text (possibly along with more styling) is held on
- *  the child {@link XWPFRun}s.</p>
+ * actual text (possibly along with more styling) is held on
+ * the child {@link XWPFRun}s.</p>
  */
 public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents, Paragraph {
     private final CTP paragraph;
     protected IBody part;
-    /** For access to the document's hyperlink, comments, tables etc */
+    /**
+     * For access to the document's hyperlink, comments, tables etc
+     */
     protected XWPFDocument document;
     protected List<XWPFRun> runs;
     protected List<IRunElement> iruns;
@@ -75,10 +80,10 @@
     public XWPFParagraph(CTP prgrph, IBody part) {
         this.paragraph = prgrph;
         this.part = part;
-        
+
         this.document = part.getXWPFDocument();
 
-        if (document==null) {
+        if (document == null) {
             throw new NullPointerException();
         }
 
@@ -88,7 +93,7 @@
         buildRunsInOrderFromXml(paragraph);
 
         // Look for bits associated with the runs
-        for(XWPFRun run : runs) {
+        for (XWPFRun run : runs) {
             CTR r = run.getCTR();
 
             // Check for bits that only apply when attached to a core document
@@ -97,13 +102,13 @@
             c.selectPath("child::*");
             while (c.toNextSelection()) {
                 XmlObject o = c.getObject();
-                if(o instanceof CTFtnEdnRef) {
-                    CTFtnEdnRef ftn = (CTFtnEdnRef)o;
+                if (o instanceof CTFtnEdnRef) {
+                    CTFtnEdnRef ftn = (CTFtnEdnRef) o;
                     footnoteText.append(" [").append(ftn.getId()).append(": ");
                     XWPFFootnote footnote =
-                        ftn.getDomNode().getLocalName().equals("footnoteReference") ?
-                            document.getFootnoteByID(ftn.getId().intValue()) :
-                            document.getEndnoteByID(ftn.getId().intValue());
+                            ftn.getDomNode().getLocalName().equals("footnoteReference") ?
+                                    document.getFootnoteByID(ftn.getId().intValue()) :
+                                    document.getEndnoteByID(ftn.getId().intValue());
 
                     boolean first = true;
                     for (XWPFParagraph p : footnote.getParagraphs()) {
@@ -123,8 +128,8 @@
 
     /**
      * Identifies (in order) the parts of the paragraph /
-     *  sub-paragraph that correspond to character text
-     *  runs, and builds the appropriate runs for these.
+     * sub-paragraph that correspond to character text
+     * runs, and builds the appropriate runs for these.
      */
     private void buildRunsInOrderFromXml(XmlObject object) {
         XmlCursor c = object.newCursor();
@@ -132,71 +137,72 @@
         while (c.toNextSelection()) {
             XmlObject o = c.getObject();
             if (o instanceof CTR) {
-               XWPFRun r = new XWPFRun((CTR) o, this);
-               runs.add(r);
-               iruns.add(r);
-           }
-           if (o instanceof CTHyperlink) {
-               CTHyperlink link = (CTHyperlink) o;
-               for (CTR r : link.getRArray()) {
-                   XWPFHyperlinkRun hr = new XWPFHyperlinkRun(link, r, this);
-                   runs.add(hr);
-                   iruns.add(hr);
-               }
-           }
-           if (o instanceof CTSdtBlock) {
-               XWPFSDT cc = new XWPFSDT((CTSdtBlock) o, part);
-               iruns.add(cc);
-           }
-           if (o instanceof CTSdtRun) {
-               XWPFSDT cc = new XWPFSDT((CTSdtRun) o, part);
-               iruns.add(cc);
-           }
-           if (o instanceof CTRunTrackChange) {
-               for (CTR r : ((CTRunTrackChange) o).getRArray()) {
-                   XWPFRun cr = new XWPFRun(r, this);
-                   runs.add(cr);
-                   iruns.add(cr);
-               }
-           }
-           if (o instanceof CTSimpleField) {
-               for (CTR r : ((CTSimpleField) o).getRArray()) {
-                   XWPFRun cr = new XWPFRun(r, this);
-                   runs.add(cr);
-                   iruns.add(cr);
-               }
-           }
+                XWPFRun r = new XWPFRun((CTR) o, this);
+                runs.add(r);
+                iruns.add(r);
+            }
+            if (o instanceof CTHyperlink) {
+                CTHyperlink link = (CTHyperlink) o;
+                for (CTR r : link.getRArray()) {
+                    XWPFHyperlinkRun hr = new XWPFHyperlinkRun(link, r, this);
+                    runs.add(hr);
+                    iruns.add(hr);
+                }
+            }
+            if (o instanceof CTSdtBlock) {
+                XWPFSDT cc = new XWPFSDT((CTSdtBlock) o, part);
+                iruns.add(cc);
+            }
+            if (o instanceof CTSdtRun) {
+                XWPFSDT cc = new XWPFSDT((CTSdtRun) o, part);
+                iruns.add(cc);
+            }
+            if (o instanceof CTRunTrackChange) {
+                for (CTR r : ((CTRunTrackChange) o).getRArray()) {
+                    XWPFRun cr = new XWPFRun(r, this);
+                    runs.add(cr);
+                    iruns.add(cr);
+                }
+            }
+            if (o instanceof CTSimpleField) {
+                for (CTR r : ((CTSimpleField) o).getRArray()) {
+                    XWPFRun cr = new XWPFRun(r, this);
+                    runs.add(cr);
+                    iruns.add(cr);
+                }
+            }
             if (o instanceof CTSmartTagRun) {
-                // Smart Tags can be nested many times. 
+                // Smart Tags can be nested many times.
                 // This implementation does not preserve the tagging information
                 buildRunsInOrderFromXml(o);
             }
         }
         c.dispose();
     }
-    
+
     @Internal
     public CTP getCTP() {
         return paragraph;
     }
 
-    public List<XWPFRun> getRuns(){
+    public List<XWPFRun> getRuns() {
         return Collections.unmodifiableList(runs);
     }
-    
+
     /**
      * Return literal runs and sdt/content control objects.
+     *
      * @return List<IRunElement>
      */
     public List<IRunElement> getIRuns() {
         return Collections.unmodifiableList(iruns);
     }
-    
-    public boolean isEmpty(){
+
+    public boolean isEmpty() {
         return !paragraph.getDomNode().hasChildNodes();
     }
 
-    public XWPFDocument getDocument(){
+    public XWPFDocument getDocument() {
         return document;
     }
 
@@ -207,8 +213,8 @@
     public String getText() {
         StringBuffer out = new StringBuffer();
         for (IRunElement run : iruns) {
-            if (run instanceof XWPFSDT){
-                out.append(((XWPFSDT)run).getContent().getText());
+            if (run instanceof XWPFSDT) {
+                out.append(((XWPFSDT) run).getContent().getText());
             } else {
                 out.append(run.toString());
             }
@@ -219,28 +225,31 @@
 
     /**
      * Return styleID of the paragraph if style exist for this paragraph
-     * if not, null will be returned     
-     * @return        styleID as String
+     * if not, null will be returned
+     *
+     * @return styleID as String
      */
     public String getStyleID() {
         if (paragraph.getPPr() != null) {
-            if(paragraph.getPPr().getPStyle()!= null) {
-                if (paragraph.getPPr().getPStyle().getVal()!= null)
+            if (paragraph.getPPr().getPStyle() != null) {
+                if (paragraph.getPPr().getPStyle().getVal() != null)
                     return paragraph.getPPr().getPStyle().getVal();
             }
         }
         return null;
-    }        
+    }
+
     /**
      * If style exist for this paragraph
      * NumId of the paragraph will be returned.
-     * If style not exist null will be returned     
-     * @return    NumID as BigInteger
+     * If style not exist null will be returned
+     *
+     * @return NumID as BigInteger
      */
-    public BigInteger getNumID(){
-        if(paragraph.getPPr()!=null){
-            if(paragraph.getPPr().getNumPr()!=null){
-                if(paragraph.getPPr().getNumPr().getNumId()!=null)
+    public BigInteger getNumID() {
+        if (paragraph.getPPr() != null) {
+            if (paragraph.getPPr().getNumPr() != null) {
+                if (paragraph.getPPr().getNumPr().getNumId() != null)
                     return paragraph.getPPr().getNumPr().getNumId().getVal();
             }
         }
@@ -248,14 +257,31 @@
     }
 
     /**
+     * setNumID of Paragraph
+     *
+     * @param numPos
+     */
+    public void setNumID(BigInteger numPos) {
+        if (paragraph.getPPr() == null)
+            paragraph.addNewPPr();
+        if (paragraph.getPPr().getNumPr() == null)
+            paragraph.getPPr().addNewNumPr();
+        if (paragraph.getPPr().getNumPr().getNumId() == null) {
+            paragraph.getPPr().getNumPr().addNewNumId();
+        }
+        paragraph.getPPr().getNumPr().getNumId().setVal(numPos);
+    }
+
+    /**
      * Returns Ilvl of the numeric style for this paragraph.
      * Returns null if this paragraph does not have numeric style.
+     *
      * @return Ilvl as BigInteger
      */
     public BigInteger getNumIlvl() {
-        if(paragraph.getPPr()!=null){
-            if(paragraph.getPPr().getNumPr()!=null){
-                if(paragraph.getPPr().getNumPr().getIlvl()!=null)
+        if (paragraph.getPPr() != null) {
+            if (paragraph.getPPr().getNumPr() != null) {
+                if (paragraph.getPPr().getNumPr().getIlvl() != null)
                     return paragraph.getPPr().getNumPr().getIlvl().getVal();
             }
         }
@@ -264,27 +290,28 @@
 
     /**
      * Returns numbering format for this paragraph, eg bullet or
-     *  lowerLetter.
+     * lowerLetter.
      * Returns null if this paragraph does not have numeric style.
      */
     public String getNumFmt() {
         BigInteger numID = getNumID();
         XWPFNumbering numbering = document.getNumbering();
-        if(numID != null && numbering != null) {
+        if (numID != null && numbering != null) {
             XWPFNum num = numbering.getNum(numID);
-            if(num != null) {
+            if (num != null) {
                 BigInteger ilvl = getNumIlvl();
                 BigInteger abstractNumId = num.getCTNum().getAbstractNumId().getVal();
                 CTAbstractNum anum = numbering.getAbstractNum(abstractNumId).getAbstractNum();
                 CTLvl level = null;
-                for(int i = 0; i < anum.sizeOfLvlArray(); i++) {
+                for (int i = 0; i < anum.sizeOfLvlArray(); i++) {
                     CTLvl lvl = anum.getLvlArray(i);
-                    if(lvl.getIlvl().equals(ilvl)) {
+                    if (lvl.getIlvl().equals(ilvl)) {
                         level = lvl;
                         break;
                     }
                 }
-                if(level != null)
+                if (level != null && level.getNumFmt() != null
+                        && level.getNumFmt().getVal() != null)
                     return level.getNumFmt().getVal().toString();
             }
         }
@@ -292,18 +319,87 @@
     }
 
     /**
-     * setNumID of Paragraph
-     * @param numPos
+     * Returns the text that should be used around the paragraph level numbers.
+     *
+     * @return a string (e.g. "%1.") or null if the value is not found.
      */
-    public void setNumID(BigInteger numPos) {
-        if(paragraph.getPPr()==null)
-            paragraph.addNewPPr();
-        if(paragraph.getPPr().getNumPr()==null)
-            paragraph.getPPr().addNewNumPr();
-        if(paragraph.getPPr().getNumPr().getNumId()==null){
-            paragraph.getPPr().getNumPr().addNewNumId();
+    public String getNumLevelText() {
+        BigInteger numID = getNumID();
+        XWPFNumbering numbering = document.getNumbering();
+        if (numID != null && numbering != null) {
+            XWPFNum num = numbering.getNum(numID);
+            if (num != null) {
+                BigInteger ilvl = getNumIlvl();
+                CTNum ctNum = num.getCTNum();
+                if (ctNum == null)
+                    return null;
+
+                CTDecimalNumber ctDecimalNumber = ctNum.getAbstractNumId();
+                if (ctDecimalNumber == null)
+                    return null;
+
+                BigInteger abstractNumId = ctDecimalNumber.getVal();
+                if (abstractNumId == null)
+                    return null;
+
+                XWPFAbstractNum xwpfAbstractNum = numbering.getAbstractNum(abstractNumId);
+
+                if (xwpfAbstractNum == null)
+                    return null;
+
+                CTAbstractNum anum = xwpfAbstractNum.getCTAbstractNum();
+
+                if (anum == null)
+                    return null;
+
+                CTLvl level = null;
+                for (int i = 0; i < anum.sizeOfLvlArray(); i++) {
+                    CTLvl lvl = anum.getLvlArray(i);
+                    if (lvl != null && lvl.getIlvl() != null && lvl.getIlvl().equals(ilvl)) {
+                        level = lvl;
+                        break;
+                    }
+                }
+                if (level != null && level.getLvlText() != null
+                        && level.getLvlText().getVal() != null)
+                    return level.getLvlText().getVal().toString();
+            }
         }
-        paragraph.getPPr().getNumPr().getNumId().setVal(numPos);
+        return null;
+    }
+
+    /**
+     * Gets the numstartOverride for the paragraph numbering for this paragraph.
+     *
+     * @return returns the overridden start number or null if there is no override for this paragraph.
+     */
+    public BigInteger getNumStartOverride() {
+        BigInteger numID = getNumID();
+        XWPFNumbering numbering = document.getNumbering();
+        if (numID != null && numbering != null) {
+            XWPFNum num = numbering.getNum(numID);
+
+            if (num != null) {
+                CTNum ctNum = num.getCTNum();
+                if (ctNum == null) {
+                    return null;
+                }
+                BigInteger ilvl = getNumIlvl();
+                CTNumLvl level = null;
+                for (int i = 0; i < ctNum.sizeOfLvlOverrideArray(); i++) {
+                    CTNumLvl ctNumLvl = ctNum.getLvlOverrideArray(i);
+                    if (ctNumLvl != null && ctNumLvl.getIlvl() != null &&
+                            ctNumLvl.getIlvl().equals(ilvl)) {
+                        level = ctNumLvl;
+                        break;
+                    }
+                }
+                if (level != null && level.getStartOverride() != null) {
+                    return level.getStartOverride().getVal();
+                }
+            }
+        }
+        return null;
     }
 
     /**
@@ -312,7 +408,7 @@
      */
     public String getParagraphText() {
         StringBuffer out = new StringBuffer();
-        for(XWPFRun run : runs) {
+        for (XWPFRun run : runs) {
             out.append(run.toString());
         }
         return out.toString();
@@ -323,7 +419,7 @@
      */
     public String getPictureText() {
         StringBuffer out = new StringBuffer();
-        for(XWPFRun run : runs) {
+        for (XWPFRun run : runs) {
             out.append(run.getPictureText());
         }
         return out.toString();
@@ -332,7 +428,7 @@
     /**
      * Returns the footnote text of the paragraph
      *
-     * @return  the footnote text or empty string if the paragraph does not have footnotes
+     * @return the footnote text or empty string if the paragraph does not have footnotes
      */
     public String getFootnoteText() {
         return footnoteText.toString();
@@ -385,6 +481,7 @@
     public int getFontAlignment() {
         return getAlignment().getValue();
     }
+
     public void setFontAlignment(int align) {
         ParagraphAlignment pAlign = ParagraphAlignment.valueOf(align);
         setAlignment(pAlign);
@@ -412,7 +509,7 @@
         CTPPr pr = getCTPPr();
         return (pr == null || !pr.isSetTextAlignment()) ? TextAlignment.AUTO
                 : TextAlignment.valueOf(pr.getTextAlignment().getVal()
-                        .intValue());
+                .intValue());
     }
 
     /**
@@ -438,9 +535,27 @@
         CTPPr pr = getCTPPr();
         CTTextAlignment textAlignment = pr.isSetTextAlignment() ? pr
                 .getTextAlignment() : pr.addNewTextAlignment();
-                STTextAlignment.Enum en = STTextAlignment.Enum
-                        .forInt(valign.getValue());
-                textAlignment.setVal(en);
+        STTextAlignment.Enum en = STTextAlignment.Enum
+                .forInt(valign.getValue());
+        textAlignment.setVal(en);
+    }
+
+    /**
+     * Specifies the border which shall be displayed above a set of paragraphs
+     * which have the same set of paragraph border settings.
+     *
+     * @return paragraphBorder - the top border for the paragraph
+     * @see #setBorderTop(Borders)
+     * @see Borders a list of all types of borders
+     */
+    public Borders getBorderTop() {
+        CTPBdr border = getCTPBrd(false);
+        CTBorder ct = null;
+        if (border != null) {
+            ct = border.getTop();
+        }
+        STBorder.Enum ptrn = (ct != null) ? ct.getVal() : STBorder.NONE;
+        return Borders.valueOf(ptrn.intValue());
     }
 
     /**
@@ -484,20 +599,20 @@
     }
 
     /**
-     * Specifies the border which shall be displayed above a set of paragraphs
-     * which have the same set of paragraph border settings.
+     * Specifies the border which shall be displayed below a set of
+     * paragraphs which have the same set of paragraph border settings.
      *
-     * @return paragraphBorder - the top border for the paragraph
-     * @see #setBorderTop(Borders)
+     * @return paragraphBorder - the bottom border for the paragraph
+     * @see #setBorderBottom(Borders)
      * @see Borders a list of all types of borders
      */
-    public Borders getBorderTop() {
+    public Borders getBorderBottom() {
         CTPBdr border = getCTPBrd(false);
         CTBorder ct = null;
         if (border != null) {
-            ct = border.getTop();
+            ct = border.getBottom();
         }
-        STBorder.Enum ptrn = (ct != null) ? ct.getVal() : STBorder.NONE;
+        STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE;
         return Borders.valueOf(ptrn.intValue());
     }
 
@@ -538,18 +653,18 @@
     }
 
     /**
-     * Specifies the border which shall be displayed below a set of
-     * paragraphs which have the same set of paragraph border settings.
+     * Specifies the border which shall be displayed on the left side of the
+     * page around the specified paragraph.
      *
-     * @return paragraphBorder - the bottom border for the paragraph
-     * @see #setBorderBottom(Borders)
-     * @see Borders a list of all types of borders
+     * @return ParagraphBorder - the left border for the paragraph
+     * @see #setBorderLeft(Borders)
+     * @see Borders for a list of all possible borders
      */
-    public Borders getBorderBottom() {
+    public Borders getBorderLeft() {
         CTPBdr border = getCTPBrd(false);
         CTBorder ct = null;
         if (border != null) {
-            ct = border.getBottom();
+            ct = border.getLeft();
         }
         STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE;
         return Borders.valueOf(ptrn.intValue());
@@ -587,18 +702,18 @@
     }
 
     /**
-     * Specifies the border which shall be displayed on the left side of the
+     * Specifies the border which shall be displayed on the right side of the
      * page around the specified paragraph.
      *
-     * @return ParagraphBorder - the left border for the paragraph
-     * @see #setBorderLeft(Borders)
+     * @return ParagraphBorder - the right border for the paragraph
+     * @see #setBorderRight(Borders)
      * @see Borders for a list of all possible borders
      */
-    public Borders getBorderLeft() {
+    public Borders getBorderRight() {
         CTPBdr border = getCTPBrd(false);
         CTBorder ct = null;
         if (border != null) {
-            ct = border.getLeft();
+            ct = border.getRight();
         }
         STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE;
         return Borders.valueOf(ptrn.intValue());
@@ -636,18 +751,18 @@
     }
 
     /**
-     * Specifies the border which shall be displayed on the right side of the
-     * page around the specified paragraph.
+     * Specifies the border which shall be displayed between each paragraph in a
+     * set of paragraphs which have the same set of paragraph border settings.
      *
-     * @return ParagraphBorder - the right border for the paragraph
-     * @see #setBorderRight(Borders)
+     * @return ParagraphBorder - the between border for the paragraph
+     * @see #setBorderBetween(Borders)
      * @see Borders for a list of all possible borders
      */
-    public Borders getBorderRight() {
+    public Borders getBorderBetween() {
         CTPBdr border = getCTPBrd(false);
         CTBorder ct = null;
         if (border != null) {
-            ct = border.getRight();
+            ct = border.getBetween();
         }
         STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE;
         return Borders.valueOf(ptrn.intValue());
@@ -689,21 +804,29 @@
     }
 
     /**
-     * Specifies the border which shall be displayed between each paragraph in a
-     * set of paragraphs which have the same set of paragraph border settings.
+     * Specifies that when rendering this document in a paginated
+     * view, the contents of this paragraph are rendered on the start of a new
+     * page in the document.
+     * <p/>
+     * If this element is omitted on a given paragraph,
+     * its value is determined by the setting previously set at any level of the
+     * style hierarchy (i.e. that previous setting remains unchanged). If this
+     * setting is never specified in the style hierarchy, then this property
+     * shall not be applied. Since the paragraph is specified to start on a new
+     * page, it begins page two even though it could have fit on page one.
+     * </p>
      *
-     * @return ParagraphBorder - the between border for the paragraph
-     * @see #setBorderBetween(Borders)
-     * @see Borders for a list of all possible borders
+     * @return boolean - if page break is set
      */
-    public Borders getBorderBetween() {
-        CTPBdr border = getCTPBrd(false);
-        CTBorder ct = null;
-        if (border != null) {
-            ct = border.getBetween();
+    public boolean isPageBreak() {
+        CTPPr ppr = getCTPPr();
+        CTOnOff ct_pageBreak = ppr.isSetPageBreakBefore() ? ppr
+                .getPageBreakBefore() : null;
+        if (ct_pageBreak != null
+                && ct_pageBreak.getVal().intValue() == STOnOff.INT_TRUE) {
+            return true;
         }
-        STBorder.Enum ptrn = ct != null ? ct.getVal() : STBorder.NONE;
-        return Borders.valueOf(ptrn.intValue());
+        return false;
     }
 
     /**
@@ -733,29 +856,14 @@
     }
 
     /**
-     * Specifies that when rendering this document in a paginated
-     * view, the contents of this paragraph are rendered on the start of a new
-     * page in the document.
-     * <p/>
-     * If this element is omitted on a given paragraph,
-     * its value is determined by the setting previously set at any level of the
-     * style hierarchy (i.e. that previous setting remains unchanged). If this
-     * setting is never specified in the style hierarchy, then this property
-     * shall not be applied. Since the paragraph is specified to start on a new
-     * page, it begins page two even though it could have fit on page one.
-     * </p>
+     * Specifies the spacing that should be added after the last line in this
+     * paragraph in the document in absolute units.
      *
-     * @return boolean - if page break is set
+     * @return int - value representing the spacing after the paragraph
      */
-    public boolean isPageBreak() {
-        CTPPr ppr = getCTPPr();
-        CTOnOff ct_pageBreak = ppr.isSetPageBreakBefore() ? ppr
-                .getPageBreakBefore() : null;
-        if (ct_pageBreak != null
-                && ct_pageBreak.getVal().intValue() == STOnOff.INT_TRUE) {
-            return true;
-        }
-        return false;
+    public int getSpacingAfter() {
+        CTSpacing spacing = getCTSpacing(false);
+        return (spacing != null && spacing.isSetAfter()) ? spacing.getAfter().intValue() : -1;
     }
 
     /**
@@ -783,11 +891,12 @@
      * Specifies the spacing that should be added after the last line in this
      * paragraph in the document in absolute units.
      *
-     * @return int - value representing the spacing after the paragraph
+     * @return bigInteger - value representing the spacing after the paragraph
+     * @see #setSpacingAfterLines(int)
      */
-    public int getSpacingAfter() {
+    public int getSpacingAfterLines() {
         CTSpacing spacing = getCTSpacing(false);
-        return (spacing != null && spacing.isSetAfter()) ? spacing.getAfter().intValue() : -1;
+        return (spacing != null && spacing.isSetAfterLines()) ? spacing.getAfterLines().intValue() : -1;
     }
 
     /**
@@ -813,20 +922,18 @@
         spacing.setAfterLines(bi);
     }
 
-
     /**
-     * Specifies the spacing that should be added after the last line in this
+     * Specifies the spacing that should be added above the first line in this
      * paragraph in the document in absolute units.
      *
-     * @return bigInteger - value representing the spacing after the paragraph
-     * @see #setSpacingAfterLines(int)
+     * @return the spacing that should be added above the first line
+     * @see #setSpacingBefore(int)
      */
-    public int getSpacingAfterLines() {
+    public int getSpacingBefore() {
         CTSpacing spacing = getCTSpacing(false);
-        return (spacing != null && spacing.isSetAfterLines()) ? spacing.getAfterLines().intValue() : -1;
+        return (spacing != null && spacing.isSetBefore()) ? spacing.getBefore().intValue() : -1;
     }
 
-
     /**
      * Specifies the spacing that should be added above the first line in this
      * paragraph in the document in absolute units.
@@ -844,15 +951,16 @@
     }
 
     /**
-     * Specifies the spacing that should be added above the first line in this
-     * paragraph in the document in absolute units.
+     * Specifies the spacing that should be added before the first line in this paragraph in the
+     * document in line units.
+     * The value of this attribute is specified in one hundredths of a line.
      *
-     * @return the spacing that should be added above the first line
-     * @see #setSpacingBefore(int)
+     * @return the spacing that should be added before the first line in this paragraph
+     * @see #setSpacingBeforeLines(int)
      */
-    public int getSpacingBefore() {
+    public int getSpacingBeforeLines() {
         CTSpacing spacing = getCTSpacing(false);
-        return (spacing != null && spacing.isSetBefore()) ? spacing.getBefore().intValue() : -1;
+        return (spacing != null && spacing.isSetBeforeLines()) ? spacing.getBeforeLines().intValue() : -1;
     }
 
     /**
@@ -874,33 +982,6 @@
     }
 
     /**
-     * Specifies the spacing that should be added before the first line in this paragraph in the
-     * document in line units.
-     * The value of this attribute is specified in one hundredths of a line.
-     *
-     * @return the spacing that should be added before the first line in this paragraph
-     * @see #setSpacingBeforeLines(int)
-     */
-    public int getSpacingBeforeLines() {
-        CTSpacing spacing = getCTSpacing(false);
-        return (spacing != null && spacing.isSetBeforeLines()) ? spacing.getBeforeLines().intValue() : -1;
-    }
-
-
-    /**
-     * Specifies how the spacing between lines is calculated as stored in the
-     * line attribute. If this attribute is omitted, then it shall be assumed to
-     * be of a value auto if a line attribute value is present.
-     *
-     * @param rule
-     * @see LineSpacingRule
-     */
-    public void setSpacingLineRule(LineSpacingRule rule) {
-        CTSpacing spacing = getCTSpacing(true);
-        spacing.setLineRule(STLineSpacingRule.Enum.forInt(rule.getValue()));
-    }
-
-    /**
      * Specifies how the spacing between lines is calculated as stored in the
      * line attribute. If this attribute is omitted, then it shall be assumed to
      * be of a value auto if a line attribute value is present.
@@ -915,24 +996,17 @@
                 .getLineRule().intValue()) : LineSpacingRule.AUTO;
     }
 
-
     /**
-     * Specifies the indentation which shall be placed between the left text
-     * margin for this paragraph and the left edge of that paragraph's content
-     * in a left to right paragraph, and the right text margin and the right
-     * edge of that paragraph's text in a right to left paragraph
-     * <p/>
-     * If this attribute is omitted, its value shall be assumed to be zero.
-     * Negative values are defined such that the text is moved past the text margin,
-     * positive values move the text inside the text margin.
-     * </p>
+     * Specifies how the spacing between lines is calculated as stored in the
+     * line attribute. If this attribute is omitted, then it shall be assumed to
+     * be of a value auto if a line attribute value is present.
      *
-     * @param indentation
+     * @param rule
+     * @see LineSpacingRule
      */
-    public void setIndentationLeft(int indentation) {
-        CTInd indent = getCTInd(true);
-        BigInteger bi = new BigInteger("" + indentation);
-        indent.setLeft(bi);
+    public void setSpacingLineRule(LineSpacingRule rule) {
+        CTSpacing spacing = getCTSpacing(true);
+        spacing.setLineRule(STLineSpacingRule.Enum.forInt(rule.getValue()));
     }
 
     /**
@@ -953,10 +1027,10 @@
         return (indentation != null && indentation.isSetLeft()) ? indentation.getLeft().intValue()
                 : -1;
     }
-    
+
     /**
-     * Specifies the indentation which shall be placed between the right text
-     * margin for this paragraph and the right edge of that paragraph's content
+     * Specifies the indentation which shall be placed between the left text
+     * margin for this paragraph and the left edge of that paragraph's content
      * in a left to right paragraph, and the right text margin and the right
      * edge of that paragraph's text in a right to left paragraph
      * <p/>
@@ -967,10 +1041,10 @@
      *
      * @param indentation
      */
-    public void setIndentationRight(int indentation) {
+    public void setIndentationLeft(int indentation) {
         CTInd indent = getCTInd(true);
         BigInteger bi = new BigInteger("" + indentation);
-        indent.setRight(bi);
+        indent.setLeft(bi);
     }
 
     /**
@@ -994,23 +1068,22 @@
     }
 
     /**
-     * Specifies the indentation which shall be removed from the first line of
-     * the parent paragraph, by moving the indentation on the first line back
-     * towards the beginning of the direction of text flow.
-     * This indentation is specified relative to the paragraph indentation which is specified for
-     * all other lines in the parent paragraph.
+     * Specifies the indentation which shall be placed between the right text
+     * margin for this paragraph and the right edge of that paragraph's content
+     * in a left to right paragraph, and the right text margin and the right
+     * edge of that paragraph's text in a right to left paragraph
      * <p/>
-     * The firstLine and hanging attributes are mutually exclusive, if both are specified, then the
-     * firstLine value is ignored.
+     * If this attribute is omitted, its value shall be assumed to be zero.
+     * Negative values are defined such that the text is moved past the text margin,
+     * positive values move the text inside the text margin.
      * </p>
      *
      * @param indentation
      */
-
-    public void setIndentationHanging(int indentation) {
+    public void setIndentationRight(int indentation) {
         CTInd indent = getCTInd(true);
         BigInteger bi = new BigInteger("" + indentation);
-        indent.setHanging(bi);
+        indent.setRight(bi);
     }
 
     /**
@@ -1032,23 +1105,23 @@
     }
 
     /**
-     * Specifies the additional indentation which shall be applied to the first
-     * line of the parent paragraph. This additional indentation is specified
-     * relative to the paragraph indentation which is specified for all other
-     * lines in the parent paragraph.
-     * The firstLine and hanging attributes are
-     * mutually exclusive, if both are specified, then the firstLine value is
-     * ignored.
-     * If the firstLineChars attribute is also specified, then this
-     * value is ignored. If this attribute is omitted, then its value shall be
-     * assumed to be zero (if needed).
+     * Specifies the indentation which shall be removed from the first line of
+     * the parent paragraph, by moving the indentation on the first line back
+     * towards the beginning of the direction of text flow.
+     * This indentation is specified relative to the paragraph indentation which is specified for
+     * all other lines in the parent paragraph.
+     * <p/>
+     * The firstLine and hanging attributes are mutually exclusive, if both are specified, then the
+     * firstLine value is ignored.
+     * </p>
      *
      * @param indentation
      */
-    public void setIndentationFirstLine(int indentation) {
+
+    public void setIndentationHanging(int indentation) {
         CTInd indent = getCTInd(true);
         BigInteger bi = new BigInteger("" + indentation);
-        indent.setFirstLine(bi);
+        indent.setHanging(bi);
     }
 
     /**
@@ -1072,9 +1145,30 @@
                 : -1;
     }
 
+    /**
+     * Specifies the additional indentation which shall be applied to the first
+     * line of the parent paragraph. This additional indentation is specified
+     * relative to the paragraph indentation which is specified for all other
+     * lines in the parent paragraph.
+     * The firstLine and hanging attributes are
+     * mutually exclusive, if both are specified, then the firstLine value is
+     * ignored.
+     * If the firstLineChars attribute is also specified, then this
+     * value is ignored. If this attribute is omitted, then its value shall be
+     * assumed to be zero (if needed).
+     *
+     * @param indentation
+     */
+    public void setIndentationFirstLine(int indentation) {
+        CTInd indent = getCTInd(true);
+        BigInteger bi = new BigInteger("" + indentation);
+        indent.setFirstLine(bi);
+    }
+
     public int getIndentFromLeft() {
         return getIndentFromLeft();
     }
+
     public void setIndentFromLeft(int dxaLeft) {
         setIndentationLeft(dxaLeft);
     }
@@ -1082,6 +1176,7 @@
     public int getIndentFromRight() {
         return getIndentFromRight();
     }
+
     public void setIndentFromRight(int dxaRight) {
         setIndentationRight(dxaRight);
     }
@@ -1089,6 +1184,7 @@
     public int getFirstLineIndent() {
         return getIndentationFirstLine();
     }
+
     public void setFirstLineIndent(int first) {
         setIndentationFirstLine(first);
     }
@@ -1099,27 +1195,6 @@
      * (breaking on the character level) or by moving the word to the following
      * line (breaking on the word level).
      *
-     * @param wrap - boolean
-     */
-    public void setWordWrapped(boolean wrap) {
-        CTOnOff wordWrap = getCTPPr().isSetWordWrap() ? getCTPPr()
-                .getWordWrap() : getCTPPr().addNewWordWrap();
-        if (wrap)
-            wordWrap.setVal(STOnOff.TRUE);
-        else
-            wordWrap.unsetVal();
-    }
-    @Deprecated
-    public void setWordWrap(boolean wrap) {
-        setWordWrapped(wrap);
-    }
-
-    /**
-     * This element specifies whether a consumer shall break Latin text which
-     * exceeds the text extents of a line by breaking the word across two lines
-     * (breaking on the character level) or by moving the word to the following
-     * line (breaking on the word level).
-     *
      * @return boolean
      */
     public boolean isWordWrapped() {
@@ -1132,13 +1207,46 @@
         }
         return false;
     }
+
+    /**
+     * This element specifies whether a consumer shall break Latin text which
+     * exceeds the text extents of a line by breaking the word across two lines
+     * (breaking on the character level) or by moving the word to the following
+     * line (breaking on the word level).
+     *
+     * @param wrap - boolean
+     */
+    public void setWordWrapped(boolean wrap) {
+        CTOnOff wordWrap = getCTPPr().isSetWordWrap() ? getCTPPr()
+                .getWordWrap() : getCTPPr().addNewWordWrap();
+        if (wrap)
+            wordWrap.setVal(STOnOff.TRUE);
+        else
+            wordWrap.unsetVal();
+    }
+
     public boolean isWordWrap() {
         return isWordWrapped();
     }
 
+    @Deprecated
+    public void setWordWrap(boolean wrap) {
+        setWordWrapped(wrap);
+    }
+
+    /**
+     * @return the style of the paragraph
+     */
+    public String getStyle() {
+        CTPPr pr = getCTPPr();
+        CTString style = pr.isSetPStyle() ? pr.getPStyle() : null;
+        return style != null ? style.getVal() : null;
+    }
+
     /**
      * This method provides a style to the paragraph
      * This is useful when, e.g. an Heading style has to be assigned
+     *
      * @param newStyle
      */
     public void setStyle(String newStyle) {
@@ -1146,15 +1254,6 @@
         CTString style = pr.getPStyle() != null ? pr.getPStyle() : pr.addNewPStyle();
         style.setVal(newStyle);
     }
-    
-    /**
-     * @return  the style of the paragraph
-     */
-    public String getStyle() {
-        CTPPr pr = getCTPPr();
-        CTString style = pr.isSetPStyle() ? pr.getPStyle() : null;
-        return style != null ? style.getVal() : null;
-    }
 
     /**
      * Get a <b>copy</b> of the currently used CTPBrd, if none is used, return
@@ -1201,20 +1300,21 @@
                 : paragraph.getPPr();
         return pr;
     }
-    
-    
+
+
     /**
-     * add a new run at the end of the position of 
+     * add a new run at the end of the position of
      * the content of parameter run
+     *
      * @param run
      */
-    protected void addRun(CTR run){
+    protected void addRun(CTR run) {
         int pos;
         pos = paragraph.sizeOfRArray();
         paragraph.addNewR();
         paragraph.setRArray(pos, run);
     }
-    
+
     /**
      * Appends a new run to this paragraph
      *
@@ -1229,14 +1329,15 @@
 
     /**
      * insert a new Run in RunArray
+     *
      * @param pos
-     * @return  the inserted run
+     * @return the inserted run
      */
-    public XWPFRun insertNewRun(int pos){
+    public XWPFRun insertNewRun(int pos) {
         if (pos >= 0 && pos <= paragraph.sizeOfRArray()) {
             CTR ctRun = paragraph.insertNewR(pos);
             XWPFRun newRun = new XWPFRun(ctRun, this);
-            
+
             // To update the iruns, find where we're going
             // in the normal runs, and go in there
             int iPos = iruns.size();
@@ -1248,10 +1349,10 @@
                 }
             }
             iruns.add(iPos, newRun);
-            
+
             // Runs itself is easy to update
             runs.add(pos, newRun);
-            
+
             return newRun;
         }
         return null;
@@ -1261,42 +1362,43 @@
      * this methods parse the paragraph and search for the string searched.
      * If it finds the string, it will return true and the position of the String
      * will be saved in the parameter startPos.
+     *
      * @param searched
      * @param startPos
      */
-    public TextSegement searchText(String searched,PositionInParagraph startPos) {
-        int startRun = startPos.getRun(), 
-            startText = startPos.getText(),
-            startChar = startPos.getChar();
+    public TextSegement searchText(String searched, PositionInParagraph startPos) {
+        int startRun = startPos.getRun(),
+                startText = startPos.getText(),
+                startChar = startPos.getChar();
         int beginRunPos = 0, candCharPos = 0;
         boolean newList = false;
         CTR[] rArray = paragraph.getRArray();
-        for (int runPos=startRun; runPos<rArray.length; runPos++) {
-            int beginTextPos = 0,beginCharPos = 0, textPos = 0,  charPos = 0;    
+        for (int runPos = startRun; runPos < rArray.length; runPos++) {
+            int beginTextPos = 0, beginCharPos = 0, textPos = 0, charPos = 0;
             CTR ctRun = rArray[runPos];
             XmlCursor c = ctRun.newCursor();
             c.selectPath("./*");
-            while(c.toNextSelection()){
+            while (c.toNextSelection()) {
                 XmlObject o = c.getObject();
-                if(o instanceof CTText){
-                    if(textPos>=startText){
-                        String candidate = ((CTText)o).getStringValue();
-                        if(runPos==startRun)
-                            charPos= startChar;
+                if (o instanceof CTText) {
+                    if (textPos >= startText) {
+                        String candidate = ((CTText) o).getStringValue();
+                        if (runPos == startRun)
+                            charPos = startChar;
                         else
                             charPos = 0;
-                        
-                        for(; charPos<candidate.length(); charPos++){
-                            if((candidate.charAt(charPos)==searched.charAt(0))&&(candCharPos==0)){
+
+                        for (; charPos < candidate.length(); charPos++) {
+                            if ((candidate.charAt(charPos) == searched.charAt(0)) && (candCharPos == 0)) {
                                 beginTextPos = textPos;
                                 beginCharPos = charPos;
                                 beginRunPos = runPos;
                                 newList = true;
                             }
-                            if(candidate.charAt(charPos)==searched.charAt(candCharPos)){
-                                if(candCharPos+1<searched.length())
+                            if (candidate.charAt(charPos) == searched.charAt(candCharPos)) {
+                                if (candCharPos + 1 < searched.length())
                                     candCharPos++;
-                                else if(newList){
+                                else if (newList) {
                                     TextSegement segement = new TextSegement();
                                     segement.setBeginRun(beginRunPos);
                                     segement.setBeginText(beginTextPos);
@@ -1306,57 +1408,55 @@
                                     segement.setEndChar(charPos);
                                     return segement;
                                 }
-                            }
-                            else {
-                                candCharPos=0;
+                            } else {
+                                candCharPos = 0;
                             }
                         }
                     }
                     textPos++;
-                }
-                else if(o instanceof CTProofErr){
+                } else if (o instanceof CTProofErr) {
                     c.removeXml();
-                }
-                else if(o instanceof CTRPr);
+                } else if (o instanceof CTRPr) ;
                     //do nothing
                 else
-                    candCharPos=0;
+                    candCharPos = 0;
             }
 
             c.dispose();
         }
         return null;
     }
-    
+
     /**
      * get a Text
+     *
      * @param segment
      */
-    public String getText(TextSegement segment){
+    public String getText(TextSegement segment) {
         int runBegin = segment.getBeginRun();
         int textBegin = segment.getBeginText();
-        int charBegin = segment.getBeginChar(); 
+        int charBegin = segment.getBeginChar();
         int runEnd = segment.getEndRun();
         int textEnd = segment.getEndText();
-        int charEnd    = segment.getEndChar();
+        int charEnd = segment.getEndChar();
         StringBuilder out = new StringBuilder();
         CTR[] rArray = paragraph.getRArray();
-        for(int i=runBegin; i<=runEnd;i++){
+        for (int i = runBegin; i <= runEnd; i++) {
             CTText[] tArray = rArray[i].getTArray();
-            int startText=0, endText = tArray.length-1;
-            if(i==runBegin)
-                startText=textBegin;
-            if(i==runEnd)
+            int startText = 0, endText = tArray.length - 1;
+            if (i == runBegin)
+                startText = textBegin;
+            if (i == runEnd)
                 endText = textEnd;
-            for(int j=startText;j<=endText;j++){
+            for (int j = startText; j <= endText; j++) {
                 String tmpText = tArray[j].getStringValue();
-                int startChar=0, endChar = tmpText.length()-1;
-                if((j==textBegin)&&(i==runBegin))
-                    startChar=charBegin;
-                if((j==textEnd)&&(i==runEnd)){
+                int startChar = 0, endChar = tmpText.length() - 1;
+                if ((j == textBegin) && (i == runBegin))
+                    startChar = charBegin;
+                if ((j == textEnd) && (i == runEnd)) {
                     endChar = charEnd;
                 }
-                out.append(tmpText.substring(startChar, endChar+1));
+                out.append(tmpText.substring(startChar, endChar + 1));
             }
         }
         return out.toString();
@@ -1364,13 +1464,18 @@
 
     /**
      * removes a Run at the position pos in the paragraph
+     *
      * @param pos
      * @return true if the run was removed
      */
-    public boolean removeRun(int pos){
+    public boolean removeRun(int pos) {
         if (pos >= 0 && pos < paragraph.sizeOfRArray()) {
-            getCTP().removeR(pos);
+            // Remove the run from our high level lists
+            XWPFRun run = runs.get(pos);
             runs.remove(pos);
+            iruns.remove(run);
+            // Remove the run from the low-level XML
+            getCTP().removeR(pos);
             return true;
         }
         return false;
@@ -1378,23 +1483,24 @@
 
     /**
      * returns the type of the BodyElement Paragraph
+     *
      * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
      */
     public BodyElementType getElementType() {
         return BodyElementType.PARAGRAPH;
     }
 
-    public IBody getBody()
-    {
+    public IBody getBody() {
         return part;
     }
 
     /**
      * returns the part of the bodyElement
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
      */
     public POIXMLDocumentPart getPart() {
-        if(part != null){
+        if (part != null) {
             return part.getPart();
         }
         return null;
@@ -1402,7 +1508,7 @@
 
     /**
      * returns the partType of the bodyPart which owns the bodyElement
-     * 
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
      */
     public BodyType getPartType() {
@@ -1411,7 +1517,7 @@
 
     /**
      * adds a new Run to the Paragraph
-     * 
+     *
      * @param r
      */
     public void addRun(XWPFRun r) {
@@ -1422,7 +1528,7 @@
 
     /**
      * return the XWPFRun-Element which owns the CTR run-Element
-     * 
+     *
      * @param r
      */
     public XWPFRun getRun(CTR r) {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
index eba552c..c69e8dd 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
@@ -28,51 +28,51 @@
 public class XWPFPicture {
 
     private CTPicture ctPic;
-    private String description;
-    private XWPFRun run;
-
-    public XWPFPicture(CTPicture ctPic, XWPFRun run){
-        this.run = run;
-        this.ctPic = ctPic;
-        description = ctPic.getNvPicPr().getCNvPr().getDescr();
+    private String description;

+    private XWPFRun run;

+

+    public XWPFPicture(CTPicture ctPic, XWPFRun run) {

+        this.run = run;

+        this.ctPic = ctPic;

+        description = ctPic.getNvPicPr().getCNvPr().getDescr();

     }
-
-    /**
-     * Link Picture with PictureData
-     * @param rel
-     */
-    public void setPictureReference(PackageRelationship rel){
-        ctPic.getBlipFill().getBlip().setEmbed(rel.getId());
-    }
-
+

+    /**

+     * Link Picture with PictureData

+     *

+     * @param rel

+     */

+    public void setPictureReference(PackageRelationship rel) {

+        ctPic.getBlipFill().getBlip().setEmbed(rel.getId());

+    }

+

     /**
      * Return the underlying CTPicture bean that holds all properties for this picture
-     *
-     * @return the underlying CTPicture bean
-     */
-    public CTPicture getCTPicture(){
-        return ctPic;
-    }
-
+     *

+     * @return the underlying CTPicture bean

+     */

+    public CTPicture getCTPicture() {

+        return ctPic;

+    }

+

     /**
-     * Get the PictureData of the Picture, if present.
-     * Note - not all kinds of picture have data
-     */
-    public XWPFPictureData getPictureData(){
-        CTBlipFillProperties blipProps = ctPic.getBlipFill();
-
-        if(blipProps == null || !blipProps.isSetBlip()) {
-            // return null if Blip data is missing
-            return null;
-        }
-
-        String blipId = blipProps.getBlip().getEmbed();
-        POIXMLDocumentPart part = run.getParent().getPart();
-        if (part != null)
-        {
-            POIXMLDocumentPart relatedPart = part.getRelationById(blipId);
-            if (relatedPart instanceof XWPFPictureData) {
-                return (XWPFPictureData) relatedPart;
+     * Get the PictureData of the Picture, if present.

+     * Note - not all kinds of picture have data

+     */

+    public XWPFPictureData getPictureData() {

+        CTBlipFillProperties blipProps = ctPic.getBlipFill();

+

+        if (blipProps == null || !blipProps.isSetBlip()) {

+            // return null if Blip data is missing

+            return null;

+        }

+

+        String blipId = blipProps.getBlip().getEmbed();

+        POIXMLDocumentPart part = run.getParent().getPart();

+        if (part != null) {

+            POIXMLDocumentPart relatedPart = part.getRelationById(blipId);

+            if (relatedPart instanceof XWPFPictureData) {

+                return (XWPFPictureData) relatedPart;

             }
         }
         return null;
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
index d7f2253..d685aef 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
@@ -40,12 +40,13 @@
 public class XWPFPictureData extends POIXMLDocumentPart {
 
     /**
-     * Relationships for each known picture type
-     */
-    protected static final POIXMLRelation[] RELATIONS;
-    static {
-        RELATIONS = new POIXMLRelation[13];
-        RELATIONS[Document.PICTURE_TYPE_EMF] = XWPFRelation.IMAGE_EMF;
+     * Relationships for each known picture type

+     */

+    protected static final POIXMLRelation[] RELATIONS;

+

+    static {

+        RELATIONS = new POIXMLRelation[13];

+        RELATIONS[Document.PICTURE_TYPE_EMF] = XWPFRelation.IMAGE_EMF;

         RELATIONS[Document.PICTURE_TYPE_WMF] = XWPFRelation.IMAGE_WMF;
         RELATIONS[Document.PICTURE_TYPE_PICT] = XWPFRelation.IMAGE_PICT;
         RELATIONS[Document.PICTURE_TYPE_JPEG] = XWPFRelation.IMAGE_JPEG;
@@ -59,24 +60,23 @@
     }
 
     private Long checksum = null;
-
-    /**
-     * Create a new XWPFGraphicData node
-     *
-     */
-    protected XWPFPictureData() {
-        super();
+

+    /**

+     * Create a new XWPFGraphicData node

+     */

+    protected XWPFPictureData() {

+        super();

     }
 
     /**
      * Construct XWPFPictureData from a package part
-     *
-     * @param part the package part holding the drawing data,
-     * @param rel  the package relationship holding this drawing,
-     * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
-     */
-    public XWPFPictureData(PackagePart part, PackageRelationship rel) {
-        super(part, rel);
+     *

+     * @param part the package part holding the drawing data,

+     * @param rel  the package relationship holding this drawing,

+     *             the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image

+     */

+    public XWPFPictureData(PackagePart part, PackageRelationship rel) {

+        super(part, rel);

     }
 
     @Override
@@ -91,12 +91,13 @@
      * You can grab the picture data directly from the underlying package part as follows:
      * <br/>
      * <code>
-     * InputStream is = getPackagePart().getInputStream();
-     * </code>
-     * </p>
-     * @return the Picture data.
-     */
-    public byte[] getData() {
+     * InputStream is = getPackagePart().getInputStream();

+     * </code>

+     * </p>

+     *

+     * @return the Picture data.

+     */

+    public byte[] getData() {

         try {
             return IOUtils.toByteArray(getPackagePart().getInputStream());
         } catch (IOException e) {
@@ -115,21 +116,22 @@
             return null;
         return name.substring(name.lastIndexOf('/') + 1);
     }
-
-    /**
-     * Suggests a file extension for this image.
-     * @return the file extension.
-     */
-    public String suggestFileExtension() {
+

+    /**

+     * Suggests a file extension for this image.

+     *

+     * @return the file extension.

+     */

+    public String suggestFileExtension() {

         return getPackagePart().getPartName().getExtension();
     }
-
-    /**
-     * Return an integer constant that specifies type of this picture
-     * 
-     * @return an integer constant that specifies type of this picture
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF
+

+    /**

+     * Return an integer constant that specifies type of this picture

+     *

+     * @return an integer constant that specifies type of this picture

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF

      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT
      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG
      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
@@ -217,13 +219,13 @@
 
                 if (!ownPackage.equals(foreignPackage)) {
                     return false;
-                }
-            }
-        }
-        
-        Long foreignChecksum = picData.getChecksum();
-        Long localChecksum = getChecksum();
-
+                }

+            }

+        }

+

+        Long foreignChecksum = picData.getChecksum();

+        Long localChecksum = getChecksum();

+

         if (!(localChecksum.equals(foreignChecksum))) {
             return false;
         }
@@ -233,13 +235,13 @@
     @Override
     public int hashCode() {
         return getChecksum().hashCode();
-    }
-
-    /**
-     * *PictureData objects store the actual content in the part directly without keeping a 
-     * copy like all others therefore we need to handle them differently.
-     */
-    @Override
+    }

+

+    /**

+     * *PictureData objects store the actual content in the part directly without keeping a

+     * copy like all others therefore we need to handle them differently.

+     */

+    @Override

     protected void prepareForCommit() {
         // do not clear the part here
     }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
index 06642fa..fae051e 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
@@ -33,7 +33,6 @@
      */
     protected static final Map<String, XWPFRelation> _table = new HashMap<String, XWPFRelation>();
 
-
     public static final XWPFRelation DOCUMENT = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
@@ -41,10 +40,10 @@
             null
     );
     public static final XWPFRelation TEMPLATE = new XWPFRelation(
-          "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml",
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
-          "/word/document.xml",
-          null
+            "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
+            "/word/document.xml",
+            null
     );
     public static final XWPFRelation MACRO_DOCUMENT = new XWPFRelation(
             "application/vnd.ms-word.document.macroEnabled.main+xml",
@@ -64,12 +63,11 @@
             "/word/glossary/document.xml",
             null
     );
-        
     public static final XWPFRelation NUMBERING = new XWPFRelation(
-    		"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
-    		"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
-    		"/word/numbering.xml",
-    		XWPFNumbering.class
+            "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
+            "/word/numbering.xml",
+            XWPFNumbering.class
     );
     public static final XWPFRelation FONT_TABLE = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
@@ -126,10 +124,10 @@
             null
     );
     public static final XWPFRelation FOOTNOTE = new XWPFRelation(
-           "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
-           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
-           "/word/footnotes.xml",
-           XWPFFootnotes.class
+            "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
+            "/word/footnotes.xml",
+            XWPFFootnotes.class
     );
     public static final XWPFRelation ENDNOTE = new XWPFRelation(
             null,
@@ -137,52 +135,51 @@
             null,
             null
     );
-
     /**
      * Supported image formats
      */
     public static final XWPFRelation IMAGE_EMF = new XWPFRelation(
-          "image/x-emf",
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/word/media/image#.emf",
-          XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_WMF = new XWPFRelation(
-	      "image/x-wmf",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.wmf",
-	      XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_PICT = new XWPFRelation(
-	      "image/pict",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.pict",
-	      XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_JPEG = new XWPFRelation(
-	      "image/jpeg",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.jpeg",
-	      XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_PNG = new XWPFRelation(
-	      "image/png",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.png",
-	      XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_DIB = new XWPFRelation(
-	      "image/dib",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.dib",
-	      XWPFPictureData.class
-	);
-	public static final XWPFRelation IMAGE_GIF = new XWPFRelation(
-	      "image/gif",
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      "/word/media/image#.gif",
-	      XWPFPictureData.class
-	);
+            "image/x-emf",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.emf",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_WMF = new XWPFRelation(
+            "image/x-wmf",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.wmf",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_PICT = new XWPFRelation(
+            "image/pict",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.pict",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_JPEG = new XWPFRelation(
+            "image/jpeg",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.jpeg",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_PNG = new XWPFRelation(
+            "image/png",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.png",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_DIB = new XWPFRelation(
+            "image/dib",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.dib",
+            XWPFPictureData.class
+    );
+    public static final XWPFRelation IMAGE_GIF = new XWPFRelation(
+            "image/gif",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/word/media/image#.gif",
+            XWPFPictureData.class
+    );
     public static final XWPFRelation IMAGE_TIFF = new XWPFRelation(
             "image/tiff",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
@@ -207,14 +204,12 @@
             "/word/media/image#.wpg",
             XWPFPictureData.class
     );
-
-	public static final XWPFRelation IMAGES = new XWPFRelation(
-	      null,
-	      "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-	      null,
-	      null
-	);	
-
+    public static final XWPFRelation IMAGES = new XWPFRelation(
+            null,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            null,
+            null
+    );
 
     private XWPFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
         super(type, rel, defaultName, cls);
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
index 07debb9..1c14bb2 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
@@ -32,19 +32,52 @@
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlString;
-import org.apache.xmlbeans.XmlToken;
-import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
-import org.openxmlformats.schemas.drawingml.x2006.main.*;
-import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
-import org.openxmlformats.schemas.drawingml.x2006.picture.CTPictureNonVisual;
-import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
-import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColor;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-
+import org.apache.xmlbeans.XmlString;

+import org.apache.xmlbeans.XmlToken;

+import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualPictureProperties;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;

+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;

+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;

+import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;

+import org.openxmlformats.schemas.drawingml.x2006.picture.CTPictureNonVisual;

+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;

+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColor;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFFCheckBox;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSignedHpsMeasure;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSignedTwipsMeasure;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTUnderline;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalAlignRun;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrClear;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;

+import org.w3c.dom.NodeList;

+import org.w3c.dom.Text;

+

 /**
  * XWPFRun object defines a region of text with a common set of properties
  */
@@ -52,22 +85,12 @@
     private CTR run;
     private String pictureText;
     private IRunBody parent;
-    private List<XWPFPicture> pictures;
-
-    /**
-     * @see <a href="http://msdn.microsoft.com/en-us/library/ff533743(v=office.12).aspx">[MS-OI29500] Run Fonts</a> 
-     */
-    public static enum FontCharRange {
-        ascii /* char 0-127 */,
-        cs /* complex symbol */,
-        eastAsia /* east asia */,
-        hAnsi /* high ansi */
-    };
-    
-    /**
-     * @param r the CTR bean which holds the run attributes
-     * @param p the parent paragraph
-     */
+    private List<XWPFPicture> pictures;

+

+    /**

+     * @param r the CTR bean which holds the run attributes

+     * @param p the parent paragraph

+     */

     @SuppressWarnings("deprecation")
     public XWPFRun(CTR r, IRunBody p) {
         this.run = r;
@@ -92,13 +115,13 @@
 
         // Look for any text in any of our pictures or drawings
         StringBuilder text = new StringBuilder();
-        List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();
-        pictTextObjs.addAll(Arrays.asList(r.getPictArray()));
-        pictTextObjs.addAll(Arrays.asList(r.getDrawingArray()));
-        for(XmlObject o : pictTextObjs) {
-            XmlObject[] ts = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
-            for (XmlObject t : ts) {
-                NodeList kids = t.getDomNode().getChildNodes();
+        List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();

+        pictTextObjs.addAll(Arrays.asList(r.getPictArray()));

+        pictTextObjs.addAll(Arrays.asList(r.getDrawingArray()));

+        for (XmlObject o : pictTextObjs) {

+            XmlObject[] ts = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");

+            for (XmlObject t : ts) {

+                NodeList kids = t.getDomNode().getChildNodes();

                 for (int n = 0; n < kids.getLength(); n++) {
                     if (kids.item(n) instanceof Text) {
                         if (text.length() > 0)
@@ -110,112 +133,134 @@
         }
         pictureText = text.toString();
 
-        // Do we have any embedded pictures?
-        // (They're a different CTPicture, under the drawingml namespace)
-        pictures = new ArrayList<XWPFPicture>();
-        for(XmlObject o : pictTextObjs) {
-            for(CTPicture pict : getCTPictures(o)) {
-                XWPFPicture picture = new XWPFPicture(pict, this);
-                pictures.add(picture);
-            }
-        }
+        // Do we have any embedded pictures?

+        // (They're a different CTPicture, under the drawingml namespace)

+        pictures = new ArrayList<XWPFPicture>();

+        for (XmlObject o : pictTextObjs) {

+            for (CTPicture pict : getCTPictures(o)) {

+                XWPFPicture picture = new XWPFPicture(pict, this);

+                pictures.add(picture);

+            }

+        }

+    }

+

+    ;

+

+    /**

+     * @deprecated Use {@link XWPFRun#XWPFRun(CTR, IRunBody)}

+     */

+    public XWPFRun(CTR r, XWPFParagraph p) {

+        this(r, (IRunBody) p);

+    }

+

+    /**

+     * Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces

+     *

+     * @param xs the string to check

+     */

+    static void preserveSpaces(XmlString xs) {

+        String text = xs.getStringValue();

+        if (text != null && (text.startsWith(" ") || text.endsWith(" "))) {

+            XmlCursor c = xs.newCursor();

+            c.toNextToken();

+            c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve");

+            c.dispose();

+        }

+    }

+

+    private List<CTPicture> getCTPictures(XmlObject o) {

+        List<CTPicture> pictures = new ArrayList<CTPicture>();

+        XmlObject[] picts = o.selectPath("declare namespace pic='" + CTPicture.type.getName().getNamespaceURI() + "' .//pic:pic");

+        for (XmlObject pict : picts) {

+            if (pict instanceof XmlAnyTypeImpl) {

+                // Pesky XmlBeans bug - see Bugzilla #49934

+                try {

+                    pict = CTPicture.Factory.parse(pict.toString());

+                } catch (XmlException e) {

+                    throw new POIXMLException(e);

+                }

+            }

+            if (pict instanceof CTPicture) {

+                pictures.add((CTPicture) pict);

+            }

+        }

+        return pictures;

     }
-    /**
-     * @deprecated Use {@link XWPFRun#XWPFRun(CTR, IRunBody)}
-     */
-    public XWPFRun(CTR r, XWPFParagraph p) {
-        this(r, (IRunBody)p);
-    }
-
-    private List<CTPicture> getCTPictures(XmlObject o) {
-        List<CTPicture> pictures = new ArrayList<CTPicture>(); 
-        XmlObject[] picts = o.selectPath("declare namespace pic='"+CTPicture.type.getName().getNamespaceURI()+"' .//pic:pic");
-        for(XmlObject pict : picts) {
-            if(pict instanceof XmlAnyTypeImpl) {
-                // Pesky XmlBeans bug - see Bugzilla #49934
-                try {
-                    pict = CTPicture.Factory.parse( pict.toString() );
-                } catch(XmlException e) {
-                    throw new POIXMLException(e);
-                }
-            }
-            if(pict instanceof CTPicture) {
-                pictures.add((CTPicture)pict);
-            }
-        }
-        return pictures;
-    }
-
-    /**
-     * Get the currently used CTR object
-     * @return ctr object
-     */
-    @Internal
+

+    /**

+     * Get the currently used CTR object

+     *

+     * @return ctr object

+     */

+    @Internal

     public CTR getCTR() {
         return run;
     }
-
-    /**
-     * Get the currently referenced paragraph/SDT object
-     * @return current parent
-     */
-    public IRunBody getParent() {
-        return parent;
-    }
-    /**
-     * Get the currently referenced paragraph, or null if a SDT object
-     * @deprecated use {@link XWPFRun#getParent()} instead
-     */
-    public XWPFParagraph getParagraph() {
-        if (parent instanceof XWPFParagraph)
-            return (XWPFParagraph)parent;
-        return null;
-    }
-
-    /**
-     * @return The {@link XWPFDocument} instance, this run belongs to, or
-     *         <code>null</code> if parent structure (paragraph > document) is not properly set.
-     */
-    public XWPFDocument getDocument() {
-        if (parent != null) {
+

+    /**

+     * Get the currently referenced paragraph/SDT object

+     *

+     * @return current parent

+     */

+    public IRunBody getParent() {

+        return parent;

+    }

+

+    /**

+     * Get the currently referenced paragraph, or null if a SDT object

+     *

+     * @deprecated use {@link XWPFRun#getParent()} instead

+     */

+    public XWPFParagraph getParagraph() {

+        if (parent instanceof XWPFParagraph)

+            return (XWPFParagraph) parent;

+        return null;

+    }

+

+    /**

+     * @return The {@link XWPFDocument} instance, this run belongs to, or

+     * <code>null</code> if parent structure (paragraph > document) is not properly set.

+     */

+    public XWPFDocument getDocument() {

+        if (parent != null) {

             return parent.getDocument();
         }
         return null;
     }
 
     /**
-     * For isBold, isItalic etc
-     */
-    private boolean isCTOnOff(CTOnOff onoff) {
-        if(! onoff.isSetVal())
-            return true;
-        if(onoff.getVal() == STOnOff.ON)
-            return true;
-        if(onoff.getVal() == STOnOff.TRUE)
-            return true;
-        return false;
-    }
+     * For isBold, isItalic etc

+     */

+    private boolean isCTOnOff(CTOnOff onoff) {

+        if (!onoff.isSetVal())

+            return true;

+        if (onoff.getVal() == STOnOff.ON)

+            return true;

+        if (onoff.getVal() == STOnOff.TRUE)

+            return true;

+        return false;

+    }

 
     /**
      * Whether the bold property shall be applied to all non-complex script
      * characters in the contents of this run when displayed in a document
      *
      * @return <code>true</code> if the bold property is applied
-     */
-    public boolean isBold() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetB()) {
-            return false;
-        }
-        return isCTOnOff(pr.getB());
+     */

+    public boolean isBold() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetB()) {

+            return false;

+        }

+        return isCTOnOff(pr.getB());

     }
-
-    /**
-     * Whether the bold property shall be applied to all non-complex script
-     * characters in the contents of this run when displayed in a document. 
-     * <p>
-     * This formatting property is a toggle property, which specifies that its
-     * behavior differs between its use within a style definition and its use as
+

+    /**

+     * Whether the bold property shall be applied to all non-complex script

+     * characters in the contents of this run when displayed in a document.

+     * <p>

+     * This formatting property is a toggle property, which specifies that its

+     * behavior differs between its use within a style definition and its use as

      * direct formatting. When used as part of a style definition, setting this
      * property shall toggle the current state of that property as specified up
      * to this point in the hierarchy (i.e. applied to not applied, and vice
@@ -241,25 +286,26 @@
     }
 
     /**
-     * Get text color. The returned value is a string in the hex form "RRGGBB".
-     */
-    public String getColor() {
-    	String color = null;
-        if (run.isSetRPr()) {
-        	CTRPr pr = run.getRPr();
-        	if (pr.isSetColor()) {
-        		CTColor clr = pr.getColor();
-        		color = clr.xgetVal().getStringValue();
-        	}
-        }
-    	return color;
-    }
-
-    /**
-     * Set text color.
-     * @param rgbStr - the desired color, in the hex form "RRGGBB".
-     */
-    public void setColor(String rgbStr) {
+     * Get text color. The returned value is a string in the hex form "RRGGBB".

+     */

+    public String getColor() {

+        String color = null;

+        if (run.isSetRPr()) {

+            CTRPr pr = run.getRPr();

+            if (pr.isSetColor()) {

+                CTColor clr = pr.getColor();

+                color = clr.xgetVal().getStringValue();

+            }

+        }

+        return color;

+    }

+

+    /**

+     * Set text color.

+     *

+     * @param rgbStr - the desired color, in the hex form "RRGGBB".

+     */

+    public void setColor(String rgbStr) {

         CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
         CTColor color = pr.isSetColor() ? pr.getColor() : pr.addNewColor();
         color.setVal(rgbStr);
@@ -285,23 +331,24 @@
     /**
      * Sets the text of this text run
      *
-     * @param value the literal text which shall be displayed in the document
-     */
-    public void setText(String value) {
-        setText(value,run.sizeOfTArray());
-    }
-
-    /**
-     * Sets the text of this text run in the 
-     *
-     * @param value the literal text which shall be displayed in the document
-     * @param pos - position in the text array (NB: 0 based)
-     */
-    public void setText(String value, int pos) {
-        if(pos > run.sizeOfTArray()) throw new ArrayIndexOutOfBoundsException("Value too large for the parameter position in XWPFRun.setText(String value,int pos)");
-        CTText t = (pos < run.sizeOfTArray() && pos >= 0) ? run.getTArray(pos) : run.addNewT();
-        t.setStringValue(value);
-        preserveSpaces(t);
+     * @param value the literal text which shall be displayed in the document

+     */

+    public void setText(String value) {

+        setText(value, run.sizeOfTArray());

+    }

+

+    /**

+     * Sets the text of this text run in the

+     *

+     * @param value the literal text which shall be displayed in the document

+     * @param pos   - position in the text array (NB: 0 based)

+     */

+    public void setText(String value, int pos) {

+        if (pos > run.sizeOfTArray())

+            throw new ArrayIndexOutOfBoundsException("Value too large for the parameter position in XWPFRun.setText(String value,int pos)");

+        CTText t = (pos < run.sizeOfTArray() && pos >= 0) ? run.getTArray(pos) : run.addNewT();

+        t.setStringValue(value);

+        preserveSpaces(t);

     }
 
     /**
@@ -309,13 +356,13 @@
      * characters in the contents of this run when displayed in a document.
      *
      * @return <code>true</code> if the italic property is applied
-     */
-    public boolean isItalic() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetI())
-            return false;
-        return isCTOnOff(pr.getI());
-    }
+     */

+    public boolean isItalic() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetI())

+            return false;

+        return isCTOnOff(pr.getI());

+    }

 
     /**
      * Whether the bold property shall be applied to all non-complex script
@@ -354,14 +401,14 @@
      *
      * @return the Underline pattern applyed to this run
      * @see UnderlinePatterns
-     */
-    public UnderlinePatterns getUnderline() {
-        CTRPr pr = run.getRPr();
-        return (pr != null && pr.isSetU() && pr.getU().getVal() != null) 
-                ? UnderlinePatterns.valueOf(pr.getU().getVal().intValue()) 
-                : UnderlinePatterns.NONE;
-    }
-
+     */

+    public UnderlinePatterns getUnderline() {

+        CTRPr pr = run.getRPr();

+        return (pr != null && pr.isSetU() && pr.getU().getVal() != null)

+                ? UnderlinePatterns.valueOf(pr.getU().getVal().intValue())

+                : UnderlinePatterns.NONE;

+    }

+

     /**
      * Specifies that the contents of this run should be displayed along with an
      * underline appearing directly below the character heigh
@@ -388,32 +435,16 @@
      * horizontal line through the center of the line.
      *
      * @return <code>true</code> if the strike property is applied
-     */
-    public boolean isStrikeThrough() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetStrike())
-            return false;
-        return isCTOnOff(pr.getStrike());
-    }
-    @Deprecated
-    public boolean isStrike() {
-        return isStrikeThrough();
-    }
-    /**
-     * Specifies that the contents of this run shall be displayed with a double
-     * horizontal line through the center of the line.
-     *
-     * @return <code>true</code> if the double strike property is applied
-     */
-    public boolean isDoubleStrikeThrough() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetDstrike())
-            return false;
-        return isCTOnOff(pr.getDstrike());
-    }
-
-    /**
-     * Specifies that the contents of this run shall be displayed with a single
+     */

+    public boolean isStrikeThrough() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetStrike())

+            return false;

+        return isCTOnOff(pr.getStrike());

+    }

+

+    /**

+     * Specifies that the contents of this run shall be displayed with a single

      * horizontal line through the center of the line.
      * <p/>
      * This formatting property is a toggle property, which specifies that its
@@ -438,86 +469,113 @@
      */
     public void setStrikeThrough(boolean value) {
         CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff strike = pr.isSetStrike() ? pr.getStrike() : pr.addNewStrike();
-        strike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    @Deprecated
-    public void setStrike(boolean value) {
-        setStrikeThrough(value);
-    }
-    /**
-     * Specifies that the contents of this run shall be displayed with a
-     * double horizontal line through the center of the line.
-     * @see #setStrikeThrough(boolean) for the rules about this
-     */
-    public void setDoubleStrikethrough(boolean value) {
+        CTOnOff strike = pr.isSetStrike() ? pr.getStrike() : pr.addNewStrike();

+        strike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    @Deprecated

+    public boolean isStrike() {

+        return isStrikeThrough();

+    }

+

+    @Deprecated

+    public void setStrike(boolean value) {

+        setStrikeThrough(value);

+    }

+

+    /**

+     * Specifies that the contents of this run shall be displayed with a double

+     * horizontal line through the center of the line.

+     *

+     * @return <code>true</code> if the double strike property is applied

+     */

+    public boolean isDoubleStrikeThrough() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetDstrike())

+            return false;

+        return isCTOnOff(pr.getDstrike());

+    }

+

+    /**

+     * Specifies that the contents of this run shall be displayed with a

+     * double horizontal line through the center of the line.

+     *

+     * @see #setStrikeThrough(boolean) for the rules about this

+     */

+    public void setDoubleStrikethrough(boolean value) {

         CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
         CTOnOff dstrike = pr.isSetDstrike() ? pr.getDstrike() : pr.addNewDstrike();
         dstrike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
-
-    public boolean isSmallCaps() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetSmallCaps())
-            return false;
-        return isCTOnOff(pr.getSmallCaps());
-    }
-    public void setSmallCaps(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff caps = pr.isSetSmallCaps() ? pr.getSmallCaps() : pr.addNewSmallCaps();
-        caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    public boolean isCapitalized() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetCaps())
-            return false;
-        return isCTOnOff(pr.getCaps());
-    }
-    public void setCapitalized(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff caps = pr.isSetCaps() ? pr.getCaps() : pr.addNewCaps();
-        caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    
-    public boolean isShadowed() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetShadow())
-            return false;
-        return isCTOnOff(pr.getShadow());
-    }
-    public void setShadow(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff shadow = pr.isSetShadow() ? pr.getShadow() : pr.addNewShadow();
-        shadow.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    
-    public boolean isImprinted() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetImprint())
-            return false;
-        return isCTOnOff(pr.getImprint());
-    }
-    public void setImprinted(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff imprinted = pr.isSetImprint() ? pr.getImprint() : pr.addNewImprint();
-        imprinted.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    
-    public boolean isEmbossed() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetEmboss())
-            return false;
-        return isCTOnOff(pr.getEmboss());
-    }
-    public void setEmbossed(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTOnOff emboss = pr.isSetEmboss() ? pr.getEmboss() : pr.addNewEmboss();
-        emboss.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
-    }
-    
-    /**
-     * Specifies the alignment which shall be applied to the contents of this
-     * run in relation to the default appearance of the run's text.
+

+    public boolean isSmallCaps() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetSmallCaps())

+            return false;

+        return isCTOnOff(pr.getSmallCaps());

+    }

+

+    public void setSmallCaps(boolean value) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTOnOff caps = pr.isSetSmallCaps() ? pr.getSmallCaps() : pr.addNewSmallCaps();

+        caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    public boolean isCapitalized() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetCaps())

+            return false;

+        return isCTOnOff(pr.getCaps());

+    }

+

+    public void setCapitalized(boolean value) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTOnOff caps = pr.isSetCaps() ? pr.getCaps() : pr.addNewCaps();

+        caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    public boolean isShadowed() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetShadow())

+            return false;

+        return isCTOnOff(pr.getShadow());

+    }

+

+    public void setShadow(boolean value) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTOnOff shadow = pr.isSetShadow() ? pr.getShadow() : pr.addNewShadow();

+        shadow.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    public boolean isImprinted() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetImprint())

+            return false;

+        return isCTOnOff(pr.getImprint());

+    }

+

+    public void setImprinted(boolean value) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTOnOff imprinted = pr.isSetImprint() ? pr.getImprint() : pr.addNewImprint();

+        imprinted.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    public boolean isEmbossed() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetEmboss())

+            return false;

+        return isCTOnOff(pr.getEmboss());

+    }

+

+    public void setEmbossed(boolean value) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTOnOff emboss = pr.isSetEmboss() ? pr.getEmboss() : pr.addNewEmboss();

+        emboss.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);

+    }

+

+    /**

+     * Specifies the alignment which shall be applied to the contents of this

+     * run in relation to the default appearance of the run's text.

      * This allows the text to be repositioned as subscript or superscript without
      * altering the font size of the run properties.
      *
@@ -550,105 +608,106 @@
         CTVerticalAlignRun ctValign = pr.isSetVertAlign() ? pr.getVertAlign() : pr.addNewVertAlign();
         ctValign.setVal(STVerticalAlignRun.Enum.forInt(valign.getValue()));
     }
-
-    public int getKerning() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetKern())
-            return 0;
-        return pr.getKern().getVal().intValue();
-    }
-    public void setKerning(int kern) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTHpsMeasure kernmes = pr.isSetKern() ? pr.getKern() : pr.addNewKern();
-        kernmes.setVal(BigInteger.valueOf(kern));
-    }
-    
-    public int getCharacterSpacing() {
-        CTRPr pr = run.getRPr();
-        if(pr == null || !pr.isSetSpacing())
-            return 0;
-        return pr.getSpacing().getVal().intValue();
-    }
-    public void setCharacterSpacing(int twips) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTSignedTwipsMeasure spc = pr.isSetSpacing() ? pr.getSpacing() : pr.addNewSpacing();
-        spc.setVal(BigInteger.valueOf(twips));
-    }
-    
-    /**
-     * Gets the fonts which shall be used to display the text contents of
-     * this run. Specifies a font which shall be used to format all characters
+

+    public int getKerning() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetKern())

+            return 0;

+        return pr.getKern().getVal().intValue();

+    }

+

+    public void setKerning(int kern) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTHpsMeasure kernmes = pr.isSetKern() ? pr.getKern() : pr.addNewKern();

+        kernmes.setVal(BigInteger.valueOf(kern));

+    }

+

+    public int getCharacterSpacing() {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetSpacing())

+            return 0;

+        return pr.getSpacing().getVal().intValue();

+    }

+

+    public void setCharacterSpacing(int twips) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTSignedTwipsMeasure spc = pr.isSetSpacing() ? pr.getSpacing() : pr.addNewSpacing();

+        spc.setVal(BigInteger.valueOf(twips));

+    }

+

+    /**

+     * Gets the fonts which shall be used to display the text contents of

+     * this run. Specifies a font which shall be used to format all characters

      * in the ASCII range (0 - 127) within the parent run
      *
      * @return a string representing the font family
      */
-    public String getFontFamily() {
-        return getFontFamily(null);
-    }
-    /**
-     * Alias for {@link #getFontFamily()}
-     */
-    public String getFontName() {
+    public String getFontFamily() {

+        return getFontFamily(null);

+    }

+

+    /**

+     * Specifies the fonts which shall be used to display the text contents of

+     * this run. Specifies a font which shall be used to format all characters

+     * in the ASCII range (0 - 127) within the parent run.

+     * <p/>

+     * Also sets the other font ranges, if they haven't been set before

+     *

+     * @param fontFamily

+     * @see FontCharRange

+     */

+    public void setFontFamily(String fontFamily) {

+        setFontFamily(fontFamily, null);

+    }

+

+    /**

+     * Alias for {@link #getFontFamily()}

+     */

+    public String getFontName() {

         return getFontFamily();
     }
 
     /**
      * Gets the font family for the specified font char range.
-     * If fcr is null, the font char range "ascii" is used
-     *
-     * @param fcr the font char range, defaults to "ansi"
-     * @return  a string representing the font famil
-     */
-    public String getFontFamily(FontCharRange fcr) {
-        CTRPr pr = run.getRPr();
-        if (pr == null || !pr.isSetRFonts()) return null;
-        
-        CTFonts fonts = pr.getRFonts();
-        switch (fcr == null ? FontCharRange.ascii : fcr) {
-        default:
-        case ascii:
-            return fonts.getAscii();
-        case cs:
-            return fonts.getCs();
-        case eastAsia:
-            return fonts.getEastAsia();
-        case hAnsi:
-            return fonts.getHAnsi();
-        }
-    }
-    
-    
-    /**
-     * Specifies the fonts which shall be used to display the text contents of
-     * this run. Specifies a font which shall be used to format all characters
-     * in the ASCII range (0 - 127) within the parent run.
-     * 
-     * Also sets the other font ranges, if they haven't been set before 
-     *
-     * @param fontFamily
-     * 
-     * @see FontCharRange
-     */
-    public void setFontFamily(String fontFamily) {
-        setFontFamily(fontFamily, null);
-    }
-    
-    /**
-     * Specifies the fonts which shall be used to display the text contents of
-     * this run. The default handling for fcr == null is to overwrite the
-     * ascii font char range with the given font family and also set all not
-     * specified font ranges
-     *
-     * @param fontFamily
-     * @param fcr FontCharRange or null for default handling
-     */
-    public void setFontFamily(String fontFamily, FontCharRange fcr) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTFonts fonts = pr.isSetRFonts() ? pr.getRFonts() : pr.addNewRFonts();
-        
-        if (fcr == null) {
-            fonts.setAscii(fontFamily);
-            if (!fonts.isSetHAnsi()) {
+     * If fcr is null, the font char range "ascii" is used

+     *

+     * @param fcr the font char range, defaults to "ansi"

+     * @return a string representing the font famil

+     */

+    public String getFontFamily(FontCharRange fcr) {

+        CTRPr pr = run.getRPr();

+        if (pr == null || !pr.isSetRFonts()) return null;

+

+        CTFonts fonts = pr.getRFonts();

+        switch (fcr == null ? FontCharRange.ascii : fcr) {

+            default:

+            case ascii:

+                return fonts.getAscii();

+            case cs:

+                return fonts.getCs();

+            case eastAsia:

+                return fonts.getEastAsia();

+            case hAnsi:

+                return fonts.getHAnsi();

+        }

+    }

+

+    /**

+     * Specifies the fonts which shall be used to display the text contents of

+     * this run. The default handling for fcr == null is to overwrite the

+     * ascii font char range with the given font family and also set all not

+     * specified font ranges

+     *

+     * @param fontFamily

+     * @param fcr        FontCharRange or null for default handling

+     */

+    public void setFontFamily(String fontFamily, FontCharRange fcr) {

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTFonts fonts = pr.isSetRFonts() ? pr.getRFonts() : pr.addNewRFonts();

+

+        if (fcr == null) {

+            fonts.setAscii(fontFamily);

+            if (!fonts.isSetHAnsi()) {

                 fonts.setHAnsi(fontFamily);
             }
             if (!fonts.isSetCs()) {
@@ -656,24 +715,24 @@
             }
             if (!fonts.isSetEastAsia()) {
                 fonts.setEastAsia(fontFamily);
-            }
-        } else {
-            switch (fcr) {
-            case ascii:
-                fonts.setAscii(fontFamily);
-                break;
-            case cs:
-                fonts.setCs(fontFamily);
-                break;
-            case eastAsia:
-                fonts.setEastAsia(fontFamily);
-                break;
-            case hAnsi:
-                fonts.setHAnsi(fontFamily);
-                break;
-            }
-        }
-    }
+            }

+        } else {

+            switch (fcr) {

+                case ascii:

+                    fonts.setAscii(fontFamily);

+                    break;

+                case cs:

+                    fonts.setCs(fontFamily);

+                    break;

+                case eastAsia:

+                    fonts.setEastAsia(fontFamily);

+                    break;

+                case hAnsi:

+                    fonts.setHAnsi(fontFamily);

+                    break;

+            }

+        }

+    }

 
     /**
      * Specifies the font size which shall be applied to all non complex script
@@ -696,13 +755,13 @@
      * be used for non complex script characters.
      * </p>
      *
-     * @param size
-     */
-    public void setFontSize(int size) {
-        BigInteger bint=new BigInteger(""+size);
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTHpsMeasure ctSize = pr.isSetSz() ? pr.getSz() : pr.addNewSz();
-        ctSize.setVal(bint.multiply(new BigInteger("2")));
+     * @param size

+     */

+    public void setFontSize(int size) {

+        BigInteger bint = new BigInteger("" + size);

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTHpsMeasure ctSize = pr.isSetSz() ? pr.getSz() : pr.addNewSz();

+        ctSize.setVal(bint.multiply(new BigInteger("2")));

     }
 
     /**
@@ -739,52 +798,54 @@
      * contents of this run.
      * </p>
      *
-     * @param val
-     */
-    public void setTextPosition(int val) {
-        BigInteger bint=new BigInteger(""+val);
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTSignedHpsMeasure position = pr.isSetPosition() ? pr.getPosition() : pr.addNewPosition();
-        position.setVal(bint);
+     * @param val

+     */

+    public void setTextPosition(int val) {

+        BigInteger bint = new BigInteger("" + val);

+        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();

+        CTSignedHpsMeasure position = pr.isSetPosition() ? pr.getPosition() : pr.addNewPosition();

+        position.setVal(bint);

+    }

+

+    /**

+     *

+     */

+    public void removeBreak() {

+        // TODO

     }
-
-    /**
-     * 
-     */
-    public void removeBreak() {
-        // TODO
-    }
-
-    /**
-     * Specifies that a break shall be placed at the current location in the run
-     * content. 
-     * A break is a special character which is used to override the
-     * normal line breaking that would be performed based on the normal layout
-     * of the document's contents. 
-     * @see #addCarriageReturn() 
-     */
-    public void addBreak() {
-        run.addNewBr();
-    } 
-
-    /**
-     * Specifies that a break shall be placed at the current location in the run
+

+    /**

+     * Specifies that a break shall be placed at the current location in the run

+     * content.

+     * A break is a special character which is used to override the

+     * normal line breaking that would be performed based on the normal layout

+     * of the document's contents.

+     *

+     * @see #addCarriageReturn()

+     */

+    public void addBreak() {

+        run.addNewBr();

+    }

+

+    /**

+     * Specifies that a break shall be placed at the current location in the run

      * content.
      * A break is a special character which is used to override the
      * normal line breaking that would be performed based on the normal layout
      * of the document's contents.
      * <p>
      * The behavior of this break character (the
-     * location where text shall be restarted after this break) shall be
-     * determined by its type values.
-     * </p>
-     * @see BreakType
-     */
-    public void addBreak(BreakType type){
-        CTBr br=run.addNewBr();
-        br.setType(STBrType.Enum.forInt(type.getValue()));
-    }
-
+     * location where text shall be restarted after this break) shall be

+     * determined by its type values.

+     * </p>

+     *

+     * @see BreakType

+     */

+    public void addBreak(BreakType type) {

+        CTBr br = run.addNewBr();

+        br.setType(STBrType.Enum.forInt(type.getValue()));

+    }

+

     /**
      * Specifies that a break shall be placed at the current location in the run
      * content. A break is a special character which is used to override the
@@ -792,31 +853,32 @@
      * of the document's contents.
      * <p>
      * The behavior of this break character (the
-     * location where text shall be restarted after this break) shall be
-     * determined by its type (in this case is BreakType.TEXT_WRAPPING as default) and clear attribute values.
-     * </p>
-     * @see BreakClear
-     */
-    public void addBreak(BreakClear clear){
-        CTBr br=run.addNewBr();
-        br.setType(STBrType.Enum.forInt(BreakType.TEXT_WRAPPING.getValue()));
-        br.setClear(STBrClear.Enum.forInt(clear.getValue()));
+     * location where text shall be restarted after this break) shall be

+     * determined by its type (in this case is BreakType.TEXT_WRAPPING as default) and clear attribute values.

+     * </p>

+     *

+     * @see BreakClear

+     */

+    public void addBreak(BreakClear clear) {

+        CTBr br = run.addNewBr();

+        br.setType(STBrType.Enum.forInt(BreakType.TEXT_WRAPPING.getValue()));

+        br.setClear(STBrClear.Enum.forInt(clear.getValue()));

+    }

+

+    /**

+     * Specifies that a tab shall be placed at the current location in

+     * the run content.

+     */

+    public void addTab() {

+        run.addNewTab();

     }
-
-    /**
-     * Specifies that a tab shall be placed at the current location in 
-     *  the run content.
-     */
-    public void addTab() {
-        run.addNewTab();
-    }
-
-    public void removeTab() {
-        //TODO
-    }    
-
-    /**
-     * Specifies that a carriage return shall be placed at the
+

+    public void removeTab() {

+        //TODO

+    }

+

+    /**

+     * Specifies that a carriage return shall be placed at the

      * current location in the run content.
      * A carriage return is used to end the current line of text in
      * Wordprocess.
@@ -830,34 +892,33 @@
     public void addCarriageReturn() {
         run.addNewCr();
     }
-
-    public void removeCarriageReturn() {
-        //TODO
-    }    
-
-    /**
-     * Adds a picture to the run. This method handles
-     *  attaching the picture data to the overall file.
-     *  
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
-     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB
-     *  
-     * @param pictureData The raw picture data
-     * @param pictureType The type of the picture, eg {@link Document#PICTURE_TYPE_JPEG}
-     * @param width width in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}
-     * @param height height in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}
-     * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException
-     * @throws IOException
-     */
-    public XWPFPicture addPicture(InputStream pictureData, int pictureType, String filename, int width, int height)
-    throws InvalidFormatException, IOException {
-        XWPFDocument doc = parent.getDocument();
-
-        // Add the picture + relationship
+

+    public void removeCarriageReturn() {

+        //TODO

+    }

+

+    /**

+     * Adds a picture to the run. This method handles

+     * attaching the picture data to the overall file.

+     *

+     * @param pictureData The raw picture data

+     * @param pictureType The type of the picture, eg {@link Document#PICTURE_TYPE_JPEG}

+     * @param width       width in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}

+     * @param height      height in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}

+     * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException

+     * @throws IOException

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG

+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB

+     */

+    public XWPFPicture addPicture(InputStream pictureData, int pictureType, String filename, int width, int height)

+            throws InvalidFormatException, IOException {

+        XWPFDocument doc = parent.getDocument();

+

+        // Add the picture + relationship

         String relationId = doc.addPictureData(pictureData, pictureType);
         XWPFPictureData picData = (XWPFPictureData) doc.getRelationById(relationId);
 
@@ -865,18 +926,18 @@
         try {
             CTDrawing drawing = run.addNewDrawing();
             CTInline inline = drawing.addNewInline();
-
-            // Do the fiddly namespace bits on the inline
-            // (We need full control of what goes where and as what)
-            String xml = 
-                "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
-                "<a:graphicData uri=\"" + CTPicture.type.getName().getNamespaceURI() + "\">" +
-                "<pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" />" +
-                "</a:graphicData>" +
-                "</a:graphic>";
-            inline.set(XmlToken.Factory.parse(xml));
-
-            // Setup the inline
+

+            // Do the fiddly namespace bits on the inline

+            // (We need full control of what goes where and as what)

+            String xml =

+                    "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +

+                            "<a:graphicData uri=\"" + CTPicture.type.getName().getNamespaceURI() + "\">" +

+                            "<pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" />" +

+                            "</a:graphicData>" +

+                            "</a:graphic>";

+            inline.set(XmlToken.Factory.parse(xml));

+

+            // Setup the inline

             inline.setDistT(0);
             inline.setDistR(0);
             inline.setDistB(0);
@@ -910,13 +971,13 @@
 
             CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr();
             cNvPicPr.addNewPicLocks().setNoChangeAspect(true);
-
-            CTBlipFillProperties blipFill = pic.addNewBlipFill();
-            CTBlip blip = blipFill.addNewBlip();
-            blip.setEmbed( picData.getPackageRelationship().getId() );
-            blipFill.addNewStretch().addNewFillRect();
-
-            CTShapeProperties spPr = pic.addNewSpPr();
+

+            CTBlipFillProperties blipFill = pic.addNewBlipFill();

+            CTBlip blip = blipFill.addNewBlip();

+            blip.setEmbed(picData.getPackageRelationship().getId());

+            blipFill.addNewStretch().addNewFillRect();

+

+            CTShapeProperties spPr = pic.addNewSpPr();

             CTTransform2D xfrm = spPr.addNewXfrm();
 
             CTPoint2D off = xfrm.addNewOff();
@@ -932,50 +993,36 @@
             prstGeom.addNewAvLst();
 
             // Finish up
-            XWPFPicture xwpfPicture = new XWPFPicture(pic, this);
-            pictures.add(xwpfPicture);
-            return xwpfPicture;
-        } catch(XmlException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Returns the embedded pictures of the run. These
-     *  are pictures which reference an external, 
-     *  embedded picture image such as a .png or .jpg
-     */
-    public List<XWPFPicture> getEmbeddedPictures() {
-        return pictures;
-    }
-
-    /**
-     * Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces
-     *
-     * @param xs    the string to check
-     */
-    static void preserveSpaces(XmlString xs) {
-        String text = xs.getStringValue();
-        if (text != null && (text.startsWith(" ") || text.endsWith(" "))) {
-            XmlCursor c = xs.newCursor();
-            c.toNextToken();
-            c.insertAttributeWithValue(new QName("http://www.w3.org/XML/1998/namespace", "space"), "preserve");
-            c.dispose();
-        }
-    }
-
-    /**
-     * Returns the string version of the text
-     */
-    public String toString() {
-        return text();
-    }
-    /**
-     * Returns the string version of the text, with tabs and
-     *  carriage returns in place of their xml equivalents.
-     */
-    public String text() {
-        StringBuffer text = new StringBuffer();
+            XWPFPicture xwpfPicture = new XWPFPicture(pic, this);

+            pictures.add(xwpfPicture);

+            return xwpfPicture;

+        } catch (XmlException e) {

+            throw new IllegalStateException(e);

+        }

+    }

+

+    /**

+     * Returns the embedded pictures of the run. These

+     * are pictures which reference an external,

+     * embedded picture image such as a .png or .jpg

+     */

+    public List<XWPFPicture> getEmbeddedPictures() {

+        return pictures;

+    }

+

+    /**

+     * Returns the string version of the text

+     */

+    public String toString() {

+        return text();

+    }

+

+    /**

+     * Returns the string version of the text, with tabs and

+     * carriage returns in place of their xml equivalents.

+     */

+    public String text() {

+        StringBuffer text = new StringBuffer();

 
         // Grab the text and tabs of the text run
         // Do so in a way that preserves the ordering
@@ -989,26 +1036,26 @@
                 //  come up as instances of CTText, but we don't want them
                 //  in the normal text output
                 if (!"w:instrText".equals(tagName)) {
-                    text.append(((CTText) o).getStringValue());
-                }
-            }
-            
-            // Complex type evaluation (currently only for extraction of check boxes)
-            if(o instanceof CTFldChar) {
-                CTFldChar ctfldChar = ((CTFldChar)o);
-                    if(ctfldChar.getFldCharType() == STFldCharType.BEGIN) {
-                        if(ctfldChar.getFfData() != null) {
-                            for(CTFFCheckBox checkBox : ctfldChar.getFfData().getCheckBoxList()) {
-                                if(checkBox.getDefault().getVal() == STOnOff.X_1) {
-                                    text.append("|X|");
-                                } else {
-                                    text.append("|_|");
-                                }
-                            }
-                        }
-                }
-            }
-
+                    text.append(((CTText) o).getStringValue());

+                }

+            }

+

+            // Complex type evaluation (currently only for extraction of check boxes)

+            if (o instanceof CTFldChar) {

+                CTFldChar ctfldChar = ((CTFldChar) o);

+                if (ctfldChar.getFldCharType() == STFldCharType.BEGIN) {

+                    if (ctfldChar.getFfData() != null) {

+                        for (CTFFCheckBox checkBox : ctfldChar.getFfData().getCheckBoxList()) {

+                            if (checkBox.getDefault().getVal() == STOnOff.X_1) {

+                                text.append("|X|");

+                            } else {

+                                text.append("|_|");

+                            }

+                        }

+                    }

+                }

+            }

+

             if (o instanceof CTPTab) {
                 text.append("\t");
             }
@@ -1030,23 +1077,33 @@
                 }
                 if ("w:cr".equals(tagName) || "cr".equals(tagName)) {
                     text.append("\n");
-                }
-            }
-            if (o instanceof CTFtnEdnRef) {
-                CTFtnEdnRef ftn = (CTFtnEdnRef)o;
-                String footnoteRef = ftn.getDomNode().getLocalName().equals("footnoteReference") ?
-                    "[footnoteRef:" + ftn.getId().intValue() + "]" : "[endnoteRef:" + ftn.getId().intValue() + "]";
-                text.append(footnoteRef);
-            }            
-        }
-
-        c.dispose();
-
-        // Any picture text?
-        if(pictureText != null && pictureText.length() > 0) {
-            text.append("\n").append(pictureText);
-        }
-
-        return text.toString();
-    }
-}
+                }

+            }

+            if (o instanceof CTFtnEdnRef) {

+                CTFtnEdnRef ftn = (CTFtnEdnRef) o;

+                String footnoteRef = ftn.getDomNode().getLocalName().equals("footnoteReference") ?

+                        "[footnoteRef:" + ftn.getId().intValue() + "]" : "[endnoteRef:" + ftn.getId().intValue() + "]";

+                text.append(footnoteRef);

+            }

+        }

+

+        c.dispose();

+

+        // Any picture text?

+        if (pictureText != null && pictureText.length() > 0) {

+            text.append("\n").append(pictureText);

+        }

+

+        return text.toString();

+    }

+

+    /**

+     * @see <a href="http://msdn.microsoft.com/en-us/library/ff533743(v=office.12).aspx">[MS-OI29500] Run Fonts</a>

+     */

+    public static enum FontCharRange {

+        ascii /* char 0-127 */,

+        cs /* complex symbol */,

+        eastAsia /* east asia */,

+        hAnsi /* high ansi */

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java
index 4a51725..fd8389e 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDT.java
@@ -17,31 +17,30 @@
 package org.apache.poi.xwpf.usermodel;
 
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;
-
-/**
- * Experimental class to offer rudimentary read-only processing of 
- *  of StructuredDocumentTags/ContentControl
- *
- * WARNING - APIs expected to change rapidly
- * 
- */
-public class XWPFSDT extends AbstractXWPFSDT
-    implements IBodyElement, IRunBody, ISDTContents, IRunElement {
-   private final ISDTContent content;
-
-   public XWPFSDT(CTSdtRun sdtRun, IBody part){
-       super(sdtRun.getSdtPr(), part);
-       this.content = new XWPFSDTContent(sdtRun.getSdtContent(), part, this);
-   }
-   
-   public XWPFSDT(CTSdtBlock block, IBody part){
-      super(block.getSdtPr(), part);
-      this.content = new XWPFSDTContent( block.getSdtContent(), part, this);
-   }
-
-   public ISDTContent getContent(){
-      return content;
-   }
-
-}
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;

+

+/**

+ * Experimental class to offer rudimentary read-only processing of

+ * of StructuredDocumentTags/ContentControl

+ * <p/>

+ * WARNING - APIs expected to change rapidly

+ */

+public class XWPFSDT extends AbstractXWPFSDT

+        implements IBodyElement, IRunBody, ISDTContents, IRunElement {

+    private final ISDTContent content;

+

+    public XWPFSDT(CTSdtRun sdtRun, IBody part) {

+        super(sdtRun.getSdtPr(), part);

+        this.content = new XWPFSDTContent(sdtRun.getSdtContent(), part, this);

+    }

+

+    public XWPFSDT(CTSdtBlock block, IBody part) {

+        super(block.getSdtPr(), part);

+        this.content = new XWPFSDTContent(block.getSdtContent(), part, this);

+    }

+

+    public ISDTContent getContent() {

+        return content;

+    }

+

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java
index 21cca3e..fb40955 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTCell.java
@@ -16,29 +16,28 @@
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtCell;
-
-/**
- * Experimental class to offer rudimentary read-only processing of 
- *  of StructuredDocumentTags/ContentControl that can appear
- *  in a table row as if a table cell.
- *  <p>
- *  These can contain one or more cells or other SDTs within them.
- *
- * WARNING - APIs expected to change rapidly
- * 
- */
-public class XWPFSDTCell extends AbstractXWPFSDT implements ICell {
-   private final XWPFSDTContentCell cellContent;
-
-   public XWPFSDTCell(CTSdtCell sdtCell, XWPFTableRow xwpfTableRow, IBody part){
-       super(sdtCell.getSdtPr(), part);
-       cellContent = new XWPFSDTContentCell(sdtCell.getSdtContent(), xwpfTableRow, part);
-   }
-
-   @Override
-   public ISDTContent getContent(){
-      return cellContent;
-   }
-   
-}
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtCell;

+

+/**

+ * Experimental class to offer rudimentary read-only processing of

+ * of StructuredDocumentTags/ContentControl that can appear

+ * in a table row as if a table cell.

+ * <p/>

+ * These can contain one or more cells or other SDTs within them.

+ * <p/>

+ * WARNING - APIs expected to change rapidly

+ */

+public class XWPFSDTCell extends AbstractXWPFSDT implements ICell {

+    private final XWPFSDTContentCell cellContent;

+

+    public XWPFSDTCell(CTSdtCell sdtCell, XWPFTableRow xwpfTableRow, IBody part) {

+        super(sdtCell.getSdtPr(), part);

+        cellContent = new XWPFSDTContentCell(sdtCell.getSdtContent(), xwpfTableRow, part);

+    }

+

+    @Override

+    public ISDTContent getContent() {

+        return cellContent;

+    }

+

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java
index 42c56b3..6942aa7 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java
@@ -16,93 +16,91 @@
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
-import java.util.ArrayList;
-import java.util.List;
-
-
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
-
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
-
-/**
- * Experimental class to offer rudimentary read-only processing of 
- *  of the contentblock of an SDT/ContentControl.
- *  
- *
- *
- * WARNING - APIs expected to change rapidly
- * 
- */
-public class XWPFSDTContent implements ISDTContent {
-
+import java.util.ArrayList;

+import java.util.List;

+

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlObject;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;

+

+/**

+ * Experimental class to offer rudimentary read-only processing of

+ * of the contentblock of an SDT/ContentControl.

+ * <p/>

+ * <p/>

+ * <p/>

+ * WARNING - APIs expected to change rapidly

+ */

+public class XWPFSDTContent implements ISDTContent {

+

     // private final IBody part;
     // private final XWPFDocument document;
     private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
     private List<XWPFTable> tables = new ArrayList<XWPFTable>();
     private List<XWPFRun> runs = new ArrayList<XWPFRun>();
-    private List<XWPFSDT> contentControls = new ArrayList<XWPFSDT>();
-    private List<ISDTContents> bodyElements = new ArrayList<ISDTContents>();
-
-    public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent){
-        for (CTR ctr : sdtRun.getRArray()){
-            XWPFRun run = new XWPFRun(ctr, parent);
-            runs.add(run);
-            bodyElements.add(run);
-        }
-    }
-    public XWPFSDTContent(CTSdtContentBlock block, IBody part, IRunBody parent){
-        XmlCursor cursor = block.newCursor();
-        cursor.selectPath("./*");
-        while (cursor.toNextSelection()) {
+    private List<XWPFSDT> contentControls = new ArrayList<XWPFSDT>();

+    private List<ISDTContents> bodyElements = new ArrayList<ISDTContents>();

+

+    public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) {

+        for (CTR ctr : sdtRun.getRArray()) {

+            XWPFRun run = new XWPFRun(ctr, parent);

+            runs.add(run);

+            bodyElements.add(run);

+        }

+    }

+

+    public XWPFSDTContent(CTSdtContentBlock block, IBody part, IRunBody parent) {

+        XmlCursor cursor = block.newCursor();

+        cursor.selectPath("./*");

+        while (cursor.toNextSelection()) {

             XmlObject o = cursor.getObject();
             if (o instanceof CTP) {
                 XWPFParagraph p = new XWPFParagraph((CTP) o, part);
                 bodyElements.add(p);
                 paragraphs.add(p);
             } else if (o instanceof CTTbl) {
-                XWPFTable t = new XWPFTable((CTTbl) o, part);
-                bodyElements.add(t);
-                tables.add(t);
-            } else if (o instanceof CTSdtBlock){
-                XWPFSDT c = new XWPFSDT(((CTSdtBlock)o), part);
-                bodyElements.add(c);
-                contentControls.add(c);
-            } else if (o instanceof CTR) {
+                XWPFTable t = new XWPFTable((CTTbl) o, part);

+                bodyElements.add(t);

+                tables.add(t);

+            } else if (o instanceof CTSdtBlock) {

+                XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part);

+                bodyElements.add(c);

+                contentControls.add(c);

+            } else if (o instanceof CTR) {

                 XWPFRun run = new XWPFRun((CTR) o, parent);
                 runs.add(run);
                 bodyElements.add(run);
             }
-        }
-    }
-
-    public String getText(){
-        StringBuilder text = new StringBuilder();
-        boolean addNewLine = false;
-        for (int i = 0; i < bodyElements.size(); i++){
-            Object o = bodyElements.get(i);
-            if (o instanceof XWPFParagraph){
-                appendParagraph((XWPFParagraph)o, text);
-                addNewLine = true;
-            } else if (o instanceof XWPFTable){
-                appendTable((XWPFTable)o, text);
-                addNewLine = true;
-            } else if (o instanceof XWPFSDT){
-                text.append(((XWPFSDT)o).getContent().getText());
-                addNewLine = true;
-            } else if (o instanceof XWPFRun){
-                text.append(((XWPFRun)o).toString());
-                addNewLine = false;
-            }
-            if (addNewLine == true && i < bodyElements.size()-1){
-                text.append("\n");
-            }
-        }
+        }

+    }

+

+    public String getText() {

+        StringBuilder text = new StringBuilder();

+        boolean addNewLine = false;

+        for (int i = 0; i < bodyElements.size(); i++) {

+            Object o = bodyElements.get(i);

+            if (o instanceof XWPFParagraph) {

+                appendParagraph((XWPFParagraph) o, text);

+                addNewLine = true;

+            } else if (o instanceof XWPFTable) {

+                appendTable((XWPFTable) o, text);

+                addNewLine = true;

+            } else if (o instanceof XWPFSDT) {

+                text.append(((XWPFSDT) o).getContent().getText());

+                addNewLine = true;

+            } else if (o instanceof XWPFRun) {

+                text.append(((XWPFRun) o).toString());

+                addNewLine = false;

+            }

+            if (addNewLine == true && i < bodyElements.size() - 1) {

+                text.append("\n");

+            }

+        }

         return text.toString();
     }
 
@@ -110,28 +108,28 @@
         //this works recursively to pull embedded tables from within cells
         for (XWPFTableRow row : table.getRows()) {
             List<ICell> cells = row.getTableICells();
-            for (int i = 0; i < cells.size(); i++) {
-                ICell cell = cells.get(i);
-                if (cell instanceof XWPFTableCell) {
-                    text.append(((XWPFTableCell)cell).getTextRecursively());
-                } else if (cell instanceof XWPFSDTCell) {
-                    text.append(((XWPFSDTCell)cell).getContent().getText());
-                }
-                if (i < cells.size()-1) {
-                    text.append("\t");
-                }
-            }
-            text.append('\n');
-        }
-    }
-    
-    private void appendParagraph(XWPFParagraph paragraph, StringBuilder text) {
-        for(IRunElement run : paragraph.getRuns()) {
-            text.append(run.toString());
-        }
-    }
-    
-    public String toString(){
-        return getText();
-    }
+            for (int i = 0; i < cells.size(); i++) {

+                ICell cell = cells.get(i);

+                if (cell instanceof XWPFTableCell) {

+                    text.append(((XWPFTableCell) cell).getTextRecursively());

+                } else if (cell instanceof XWPFSDTCell) {

+                    text.append(((XWPFSDTCell) cell).getContent().getText());

+                }

+                if (i < cells.size() - 1) {

+                    text.append("\t");

+                }

+            }

+            text.append('\n');

+        }

+    }

+

+    private void appendParagraph(XWPFParagraph paragraph, StringBuilder text) {

+        for (IRunElement run : paragraph.getRuns()) {

+            text.append(run.toString());

+        }

+    }

+

+    public String toString() {

+        return getText();

+    }

 }

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java
index 25e258a..17f388b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContentCell.java
@@ -18,54 +18,52 @@
 
 
 import javax.xml.namespace.QName;
-
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlCursor.TokenType;
-
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentCell;
-
-
-
-/**
- * Experimental class to offer rudimentary read-only processing of 
- *  of the XWPFSDTCellContent.  
-
- * WARNING - APIs expected to change rapidly
- * 
- */
-public class XWPFSDTContentCell implements ISDTContent {
-
+

+import org.apache.xmlbeans.XmlCursor;

+import org.apache.xmlbeans.XmlCursor.TokenType;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentCell;

+

+

+/**

+ * Experimental class to offer rudimentary read-only processing of

+ * of the XWPFSDTCellContent.

+ * <p/>

+ * WARNING - APIs expected to change rapidly

+ */

+public class XWPFSDTContentCell implements ISDTContent {

+

     //A full implementation would grab the icells
     //that a content cell can contain.  This would require
     //significant changes, including changing the notion that the
     //parent of a cell can be not just a row, but an sdt.
     //For now we are just grabbing the text out of the text tokentypes.
 
-    //private List<ICell> cells = new ArrayList<ICell>().
+    //private List<ICell> cells = new ArrayList<ICell>().

+

+    private String text = "";

+

+    public XWPFSDTContentCell(CTSdtContentCell sdtContentCell,

+                              XWPFTableRow xwpfTableRow, IBody part) {

+        super();

+        StringBuilder sb = new StringBuilder();

+        XmlCursor cursor = sdtContentCell.newCursor();

 
-    private String text = "";
-    public XWPFSDTContentCell(CTSdtContentCell sdtContentCell, 
-            XWPFTableRow xwpfTableRow, IBody part){
-        super();
-        StringBuilder sb = new StringBuilder();
-        XmlCursor cursor = sdtContentCell.newCursor();
-
-        //keep track of the following,
-        //and add "\n" only before the start of a body
-        //element if it is not the first body element.
-        
-        //index of cell in row
-        int tcCnt = 0;
-        //count of body objects
+        //keep track of the following,

+        //and add "\n" only before the start of a body

+        //element if it is not the first body element.

+

+        //index of cell in row

+        int tcCnt = 0;

+        //count of body objects

         int iBodyCnt = 0;
         int depth = 1;
-
-        while (cursor.hasNextToken() && depth > 0) {
-            TokenType t = cursor.toNextToken();
-            if (t.isText()){
-                sb.append(cursor.getTextValue());
-            } else if (isStartToken(cursor, "tr")) {
-                tcCnt = 0;
+

+        while (cursor.hasNextToken() && depth > 0) {

+            TokenType t = cursor.toNextToken();

+            if (t.isText()) {

+                sb.append(cursor.getTextValue());

+            } else if (isStartToken(cursor, "tr")) {

+                tcCnt = 0;

                 iBodyCnt = 0;
             } else if (isStartToken(cursor, "tc")) {
                 if (tcCnt++ > 0) {
@@ -77,38 +75,37 @@
                     isStartToken(cursor, "sdt")) {
                 if (iBodyCnt > 0) {
                     sb.append("\n");
-                }
-                iBodyCnt++;
-            }
-            if (cursor.isStart()){
-                depth++;
-            } else if (cursor.isEnd()){
-                depth--;
-            }
-        }
-        text = sb.toString();
-    }
-
-
-
-    private boolean isStartToken(XmlCursor cursor, String string) {
-        if (! cursor.isStart()) {
-            return false;
-        }
-        QName qName = cursor.getName();
+                }

+                iBodyCnt++;

+            }

+            if (cursor.isStart()) {

+                depth++;

+            } else if (cursor.isEnd()) {

+                depth--;

+            }

+        }

+        text = sb.toString();

+    }

+

+

+    private boolean isStartToken(XmlCursor cursor, String string) {

+        if (!cursor.isStart()) {

+            return false;

+        }

+        QName qName = cursor.getName();

         if (qName != null && qName.getLocalPart() != null &&
                 qName.getLocalPart().equals(string)) {
             return true;
         }
         return false;
-    }
-
-
-    public String getText(){
-        return text;
-    }
-
-    public String toString(){
-        return getText();
-    }
+    }

+

+

+    public String getText() {

+        return text;

+    }

+

+    public String toString() {

+        return getText();

+    }

 }

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
index 3dcc41a..6ce7e2a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
@@ -59,8 +59,7 @@
     }
 
     @Override
-    protected void onDocumentRead() throws IOException
-    {
+    protected void onDocumentRead() throws IOException {
         super.onDocumentRead();
         readFrom(getPackagePart().getInputStream());
     }
@@ -74,17 +73,18 @@
      * <pre>
      *    &lt;w:zoom w:percent="50" /&gt;
      * <pre>
+     *
      * @return percentage as an integer of zoom level
      */
     public long getZoomPercent() {
-       CTZoom zoom;
-       if (!ctSettings.isSetZoom()) {
-          zoom = ctSettings.addNewZoom();
-       } else {
-          zoom = ctSettings.getZoom();
-       }
+        CTZoom zoom;
+        if (!ctSettings.isSetZoom()) {
+            zoom = ctSettings.addNewZoom();
+        } else {
+            zoom = ctSettings.getZoom();
+        }
 
-       return zoom.getPercent().longValue();
+        return zoom.getPercent().longValue();
     }
 
     /**
@@ -92,31 +92,31 @@
      * In the zoom tag inside settings.xml file <br/>
      * it sets the value of zoom
      * <br/>
-     * sample snippet from settings.xml 
+     * sample snippet from settings.xml
      * <pre>
-     *    &lt;w:zoom w:percent="50" /&gt; 
+     *    &lt;w:zoom w:percent="50" /&gt;
      * <pre>
      */
     public void setZoomPercent(long zoomPercent) {
-       if (! ctSettings.isSetZoom()) {
-          ctSettings.addNewZoom();
-       }
-       CTZoom zoom = ctSettings.getZoom();
-       zoom.setPercent(BigInteger.valueOf(zoomPercent));
+        if (!ctSettings.isSetZoom()) {
+            ctSettings.addNewZoom();
+        }
+        CTZoom zoom = ctSettings.getZoom();
+        zoom.setPercent(BigInteger.valueOf(zoomPercent));
     }
 
     /**
      * Verifies the documentProtection tag inside settings.xml file <br/>
      * if the protection is enforced (w:enforcement="1") <br/>
      * and if the kind of protection equals to passed (STDocProtect.Enum editValue) <br/>
-     * 
+     * <p/>
      * <br/>
      * sample snippet from settings.xml
      * <pre>
      *     &lt;w:settings  ... &gt;
      *         &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
      * </pre>
-     * 
+     *
      * @return true if documentProtection is enforced with option readOnly
      */
     public boolean isEnforcedWith(STDocProtect.Enum editValue) {
@@ -152,23 +152,23 @@
      * <br/>
      * sample snippet from settings.xml
      * <pre>
-     *   &lt;w:documentProtection w:edit=&quot;[passed editValue]&quot; w:enforcement=&quot;1&quot; 
+     *   &lt;w:documentProtection w:edit=&quot;[passed editValue]&quot; w:enforcement=&quot;1&quot;
      *       w:cryptProviderType=&quot;rsaAES&quot; w:cryptAlgorithmClass=&quot;hash&quot;
      *       w:cryptAlgorithmType=&quot;typeAny&quot; w:cryptAlgorithmSid=&quot;14&quot;
      *       w:cryptSpinCount=&quot;100000&quot; w:hash=&quot;...&quot; w:salt=&quot;....&quot;
      *   /&gt;
      * </pre>
-     * 
+     *
      * @param editValue the protection type
-     * @param password the plaintext password, if null no password will be applied
-     * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
-     *   if null, it will default default to sha1
+     * @param password  the plaintext password, if null no password will be applied
+     * @param hashAlgo  the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
+     *                  if null, it will default default to sha1
      */
     public void setEnforcementEditValue(org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect.Enum editValue,
-            String password, HashAlgorithm hashAlgo) {
+                                        String password, HashAlgorithm hashAlgo) {
         safeGetDocumentProtection().setEnforcement(STOnOff.X_1);
         safeGetDocumentProtection().setEdit(editValue);
-        
+
         if (password == null) {
             if (safeGetDocumentProtection().isSetCryptProviderType()) {
                 safeGetDocumentProtection().unsetCryptProviderType();
@@ -177,23 +177,23 @@
             if (safeGetDocumentProtection().isSetCryptAlgorithmClass()) {
                 safeGetDocumentProtection().unsetCryptAlgorithmClass();
             }
-            
+
             if (safeGetDocumentProtection().isSetCryptAlgorithmType()) {
                 safeGetDocumentProtection().unsetCryptAlgorithmType();
             }
-            
+
             if (safeGetDocumentProtection().isSetCryptAlgorithmSid()) {
                 safeGetDocumentProtection().unsetCryptAlgorithmSid();
             }
-            
+
             if (safeGetDocumentProtection().isSetSalt()) {
                 safeGetDocumentProtection().unsetSalt();
             }
-            
+
             if (safeGetDocumentProtection().isSetCryptSpinCount()) {
                 safeGetDocumentProtection().unsetCryptSpinCount();
             }
-            
+
             if (safeGetDocumentProtection().isSetHash()) {
                 safeGetDocumentProtection().unsetHash();
             }
@@ -201,47 +201,47 @@
             final STCryptProv.Enum providerType;
             final int sid;
             switch (hashAlgo) {
-            case md2:
-                providerType = STCryptProv.RSA_FULL;
-                sid = 1;
-                break;
-            case md4:
-                providerType = STCryptProv.RSA_FULL;
-                sid = 2;
-                break;
-            case md5:
-                providerType = STCryptProv.RSA_FULL;
-                sid = 3;
-                break;
-            case sha1:
-                providerType = STCryptProv.RSA_FULL;
-                sid = 4;
-                break;
-            case sha256:
-                providerType = STCryptProv.RSA_AES;
-                sid = 12;
-                break;
-            case sha384:
-                providerType = STCryptProv.RSA_AES;
-                sid = 13;
-                break;
-            case sha512:
-                providerType = STCryptProv.RSA_AES;
-                sid = 14;
-                break;
-            default:
-                throw new EncryptedDocumentException
-                ("Hash algorithm '"+hashAlgo+"' is not supported for document write protection.");
+                case md2:
+                    providerType = STCryptProv.RSA_FULL;
+                    sid = 1;
+                    break;
+                case md4:
+                    providerType = STCryptProv.RSA_FULL;
+                    sid = 2;
+                    break;
+                case md5:
+                    providerType = STCryptProv.RSA_FULL;
+                    sid = 3;
+                    break;
+                case sha1:
+                    providerType = STCryptProv.RSA_FULL;
+                    sid = 4;
+                    break;
+                case sha256:
+                    providerType = STCryptProv.RSA_AES;
+                    sid = 12;
+                    break;
+                case sha384:
+                    providerType = STCryptProv.RSA_AES;
+                    sid = 13;
+                    break;
+                case sha512:
+                    providerType = STCryptProv.RSA_AES;
+                    sid = 14;
+                    break;
+                default:
+                    throw new EncryptedDocumentException
+                            ("Hash algorithm '" + hashAlgo + "' is not supported for document write protection.");
             }
 
-        
-            SecureRandom random = new SecureRandom(); 
+
+            SecureRandom random = new SecureRandom();
             byte salt[] = random.generateSeed(16);
-    
+
             // Iterations specifies the number of times the hashing function shall be iteratively run (using each
             // iteration's result as the input for the next iteration).
             int spinCount = 100000;
-    
+
             if (hashAlgo == null) hashAlgo = HashAlgorithm.sha1;
 
             String legacyHash = CryptoFunctions.xorHashPasswordReversed(password);
@@ -257,7 +257,7 @@
             safeGetDocumentProtection().setCryptAlgorithmClass(STAlgClass.HASH);
             safeGetDocumentProtection().setCryptProviderType(providerType);
             safeGetDocumentProtection().setCryptAlgorithmSid(BigInteger.valueOf(sid));
-        }        
+        }
     }
 
     /**
@@ -271,30 +271,45 @@
         byte hash[] = safeGetDocumentProtection().getHash();
         byte salt[] = safeGetDocumentProtection().getSalt();
         BigInteger spinCount = safeGetDocumentProtection().getCryptSpinCount();
-        
+
         if (sid == null || hash == null || salt == null || spinCount == null) return false;
-        
+
         HashAlgorithm hashAlgo;
         switch (sid.intValue()) {
-        case 1: hashAlgo = HashAlgorithm.md2; break;
-        case 2: hashAlgo = HashAlgorithm.md4; break;
-        case 3: hashAlgo = HashAlgorithm.md5; break;
-        case 4: hashAlgo = HashAlgorithm.sha1; break;
-        case 12: hashAlgo = HashAlgorithm.sha256; break;
-        case 13: hashAlgo = HashAlgorithm.sha384; break;
-        case 14: hashAlgo = HashAlgorithm.sha512; break;
-        default: return false;
+            case 1:
+                hashAlgo = HashAlgorithm.md2;
+                break;
+            case 2:
+                hashAlgo = HashAlgorithm.md4;
+                break;
+            case 3:
+                hashAlgo = HashAlgorithm.md5;
+                break;
+            case 4:
+                hashAlgo = HashAlgorithm.sha1;
+                break;
+            case 12:
+                hashAlgo = HashAlgorithm.sha256;
+                break;
+            case 13:
+                hashAlgo = HashAlgorithm.sha384;
+                break;
+            case 14:
+                hashAlgo = HashAlgorithm.sha512;
+                break;
+            default:
+                return false;
         }
-        
+
         String legacyHash = CryptoFunctions.xorHashPasswordReversed(password);
         // Implementation Notes List:
         // --> In this third stage, the reversed byte order legacy hash from the second stage shall
         //     be converted to Unicode hex string representation
         byte hash2[] = CryptoFunctions.hashPassword(legacyHash, hashAlgo, salt, spinCount.intValue(), false);
-        
+
         return Arrays.equals(hash, hash2);
     }
-    
+
     /**
      * Removes protection enforcement.<br/>
      * In the documentProtection tag inside settings.xml file <br/>
@@ -308,18 +323,18 @@
      * Enforces fields update on document open (in Word).
      * In the settings.xml file <br/>
      * sets the updateSettings value to true (w:updateSettings w:val="true")
-     * 
-     *  NOTICES:
-     *  <ul>
-     *  	<li>Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?"
-     *           (if "Update automatic links at open" is enabled)</li>
-     *  	<li>Flag is removed after saving with changes in Word </li>
-     *  </ul> 
+     * <p/>
+     * NOTICES:
+     * <ul>
+     * <li>Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?"
+     * (if "Update automatic links at open" is enabled)</li>
+     * <li>Flag is removed after saving with changes in Word </li>
+     * </ul>
      */
     public void setUpdateFields() {
-    	CTOnOff onOff = CTOnOff.Factory.newInstance();
-    	onOff.setVal(STOnOff.TRUE);
-    	ctSettings.setUpdateFields(onOff);
+        CTOnOff onOff = CTOnOff.Factory.newInstance();
+        onOff.setVal(STOnOff.TRUE);
+        ctSettings.setUpdateFields(onOff);
     }
 
     boolean isUpdateFields() {
@@ -328,7 +343,7 @@
 
     /**
      * Check if revision tracking is turned on.
-     * 
+     *
      * @return <code>true</code> if revision tracking is turned on
      */
     public boolean isTrackRevisions() {
@@ -337,16 +352,16 @@
 
     /**
      * Enable or disable revision tracking.
-     * 
+     *
      * @param enable <code>true</code> to  turn on revision tracking, <code>false</code> to turn off revision tracking
      */
     public void setTrackRevisions(boolean enable) {
-        if(enable) {
-            if(!ctSettings.isSetTrackRevisions()) {
+        if (enable) {
+            if (!ctSettings.isSetTrackRevisions()) {
                 ctSettings.addNewTrackRevisions();
             }
         } else {
-            if(ctSettings.isSetTrackRevisions()) {
+            if (ctSettings.isSetTrackRevisions()) {
                 ctSettings.unsetTrackRevisions();
             }
         }
@@ -355,7 +370,7 @@
     @Override
     protected void commit() throws IOException {
         if (ctSettings == null) {
-           throw new IllegalStateException("Unable to write out settings that were never read in!");
+            throw new IllegalStateException("Unable to write out settings that were never read in!");
         }
 
         XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
index 2ceff97..a6ebdcc 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
@@ -19,128 +19,141 @@
 
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
-
-/**
- * @author Philipp Epp
- *
- */
-public class XWPFStyle {
-	
-	 private CTStyle ctStyle;
-	 protected XWPFStyles styles;
-
-	 /**
-	  * constructor
-	  * @param style
-	  */
-	 public XWPFStyle(CTStyle style){
-		 this(style,null);
-	 }
-	 /**
-	  * constructor
-	  * @param style
-	  * @param styles
-	  */
-	 public XWPFStyle(CTStyle style, XWPFStyles styles){
-		 this.ctStyle  = style;
-		 this.styles = styles;
-	 }
-
-	 /**
-	  * get StyleID of the style
-	  * @return styleID		StyleID of the style
-	  */
-	 public String getStyleId(){
-		 return ctStyle.getStyleId();
-	 }
-	 
-	 /**
-	  * get Type of the Style
-	  * @return	ctType 
-	  */
-	 public STStyleType.Enum getType(){
-		 return ctStyle.getType();
-	 }
-	 
-	 /**
-	  * set style
-	  * @param style		
-	  */
-	 public void setStyle(CTStyle style){
-		 this.ctStyle = style;
-	 }
-	 /**
-	  * get ctStyle
-	  * @return	ctStyle
-	  */
-	 public CTStyle getCTStyle(){
-		 return this.ctStyle;
-	 }
-	 /**
-	  * set styleID
-	  * @param styleId
-	  */
-	 public void setStyleId(String styleId){
-		 ctStyle.setStyleId(styleId);
-	 }
-	 
-	 /**
-	  * set styleType
-	  * @param type
-	  */
-	 public void setType(STStyleType.Enum type){
-		 ctStyle.setType(type);
-	 }
-	 /**
-	  * get styles
-	  * @return styles		the styles to which this style belongs
-	  */
-	 public XWPFStyles getStyles(){
-		 return styles;
-	 }
-	 
-	 public String getBasisStyleID(){
-		 if(ctStyle.getBasedOn()!=null)
-			 return ctStyle.getBasedOn().getVal();
-		 else
-			 return null;
-	 }
-	 
-	 
-	 /**
-	  * get StyleID of the linked Style
-	  */
-	 public String getLinkStyleID(){
-		 if (ctStyle.getLink()!=null)
-			 return ctStyle.getLink().getVal();
-		 else
-			 return null;
-	 }
-	 
-	 /**
-	  * get StyleID of the next style
-	  */
-	 public String getNextStyleID(){
-		if(ctStyle.getNext()!=null)
-			return ctStyle.getNext().getVal();
-		else
-			return null;
-	 }
-	 
-	 public String getName() {
-	    if(ctStyle.isSetName()) 
-	       return ctStyle.getName().getVal();
-	    return null;
-	 }
-	 
-	 /**
-	  * compares the names of the Styles 
-	  * @param compStyle
-	  */
-	 public boolean hasSameName(XWPFStyle compStyle){
-		CTStyle ctCompStyle = compStyle.getCTStyle();
-		String name = ctCompStyle.getName().getVal();
-		return name.equals(ctStyle.getName().getVal());
-	 }
-	 
-}//end class
+

+/**

+ * @author Philipp Epp

+ */

+public class XWPFStyle {

+

+    protected XWPFStyles styles;

+    private CTStyle ctStyle;

+

+    /**

+     * constructor

+     *

+     * @param style

+     */

+    public XWPFStyle(CTStyle style) {

+        this(style, null);

+    }

+

+    /**

+     * constructor

+     *

+     * @param style

+     * @param styles

+     */

+    public XWPFStyle(CTStyle style, XWPFStyles styles) {

+        this.ctStyle = style;

+        this.styles = styles;

+    }

+

+    /**

+     * get StyleID of the style

+     *

+     * @return styleID        StyleID of the style

+     */

+    public String getStyleId() {

+        return ctStyle.getStyleId();

+    }

+

+    /**

+     * set styleID

+     *

+     * @param styleId

+     */

+    public void setStyleId(String styleId) {

+        ctStyle.setStyleId(styleId);

+    }

+

+    /**

+     * get Type of the Style

+     *

+     * @return ctType

+     */

+    public STStyleType.Enum getType() {

+        return ctStyle.getType();

+    }

+

+    /**

+     * set styleType

+     *

+     * @param type

+     */

+    public void setType(STStyleType.Enum type) {

+        ctStyle.setType(type);

+    }

+

+    /**

+     * set style

+     *

+     * @param style

+     */

+    public void setStyle(CTStyle style) {

+        this.ctStyle = style;

+    }

+

+    /**

+     * get ctStyle

+     *

+     * @return ctStyle

+     */

+    public CTStyle getCTStyle() {

+        return this.ctStyle;

+    }

+

+    /**

+     * get styles

+     *

+     * @return styles        the styles to which this style belongs

+     */

+    public XWPFStyles getStyles() {

+        return styles;

+    }

+

+    public String getBasisStyleID() {

+        if (ctStyle.getBasedOn() != null)

+            return ctStyle.getBasedOn().getVal();

+        else

+            return null;

+    }

+

+

+    /**

+     * get StyleID of the linked Style

+     */

+    public String getLinkStyleID() {

+        if (ctStyle.getLink() != null)

+            return ctStyle.getLink().getVal();

+        else

+            return null;

+    }

+

+    /**

+     * get StyleID of the next style

+     */

+    public String getNextStyleID() {

+        if (ctStyle.getNext() != null)

+            return ctStyle.getNext().getVal();

+        else

+            return null;

+    }

+

+    public String getName() {

+        if (ctStyle.isSetName())

+            return ctStyle.getName().getVal();

+        return null;

+    }

+

+    /**

+     * compares the names of the Styles

+     *

+     * @param compStyle

+     */

+    public boolean hasSameName(XWPFStyle compStyle) {

+        CTStyle ctCompStyle = compStyle.getCTStyle();

+        String name = ctCompStyle.getName().getVal();

+        return name.equals(ctStyle.getName().getVal());

+    }

+

+}//end class

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
index 824d39d..ed39601 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
@@ -31,281 +31,295 @@
 import org.apache.poi.POIXMLException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.openxml4j.opc.PackageRelationship;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;
-/**
- * @author Philipp Epp
- *
- */
-public class XWPFStyles extends POIXMLDocumentPart{
-    
-    private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();
-    private CTStyles ctStyles;
-    XWPFLatentStyles latentStyles;
+import org.apache.poi.openxml4j.opc.PackageRelationship;

+import org.apache.xmlbeans.XmlException;

+import org.apache.xmlbeans.XmlOptions;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPrDefault;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;

+

+/**

+ * Holds details of built-in, default and user styles, which

+ * apply to tables / paragraphs / lists etc.

+ * Text within one of those with custom stylings has the style

+ * information stored in the {@link XWPFRun}

+ */

+public class XWPFStyles extends POIXMLDocumentPart {

+    private CTStyles ctStyles;

+    private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();

+

+    private XWPFLatentStyles latentStyles;

+    private XWPFDefaultRunStyle defaultRunStyle;

+    private XWPFDefaultParagraphStyle defaultParaStyle;

 
     /**
      * Construct XWPFStyles from a package part
      *
-     * @param part the package part holding the data of the styles,
-     * @param rel  the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
-     */
-
-	public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
-		super(part, rel);
-	}
-
-	/**
-	 * Construct XWPFStyles from scratch for a new document.
-	 */
-	public XWPFStyles() {
-	}
-
-   /**
-    * Read document
-    */
-   @Override
-   protected void onDocumentRead() throws IOException{
-      StylesDocument stylesDoc;
-      try {
-         InputStream is = getPackagePart().getInputStream();
-         stylesDoc = StylesDocument.Factory.parse(is);
-         setStyles(stylesDoc.getStyles());
-         latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this);
-      } catch (XmlException e) {
-         throw new POIXMLException("Unable to read styles", e);
-      }
-      
-      
-   }
-	
-   @Override
-   protected void commit() throws IOException {
-      if (ctStyles == null) {
-         throw new IllegalStateException("Unable to write out styles that were never read in!");
-      }
-      
-      XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-      xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
-      Map<String,String> map = new HashMap<String,String>();
-      map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
-      map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
-      xmlOptions.setSaveSuggestedPrefixes(map);
-      PackagePart part = getPackagePart();
-      OutputStream out = part.getOutputStream();
-      ctStyles.save(out, xmlOptions);
-      out.close();
-   }
-	
+     * @param part the package part holding the data of the styles,

+     * @param rel  the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"

+     */

+    public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException {

+        super(part, rel);

+    }

+

     /**
-     * Sets the ctStyles
-     * @param styles
+     * Construct XWPFStyles from scratch for a new document.
      */
-    @SuppressWarnings("deprecation")
-    public void setStyles(CTStyles styles) {
-       ctStyles = styles;
-       
-       // Build up all the style objects
-       for(CTStyle style : ctStyles.getStyleArray()) {
-          listStyle.add(new XWPFStyle(style, this));
-       }
+    public XWPFStyles() {
     }
-	
-	 /**
-	  * checks whether style with styleID exist
-	  * @param styleID		styleID of the Style in the style-Document
-	  * @return				true if style exist, false if style not exist
-	  */
-	public boolean styleExist(String styleID){
-		for (XWPFStyle style : listStyle) {
-			if (style.getStyleId().equals(styleID))
-				return true;
-		}
-		return false;
-	}
-	/**
-	 * add a style to the document
-	 * @param style				
-	 * @throws IOException		 
-	 */
-	public void addStyle(XWPFStyle style){
-		listStyle.add(style);
-		ctStyles.addNewStyle();
-		int pos = ctStyles.sizeOfStyleArray() - 1;
-		ctStyles.setStyleArray(pos, style.getCTStyle());
-	}
-	/**
-	 *get style by a styleID 
-	 * @param styleID	styleID of the searched style
-	 * @return style
-	 */
-	public XWPFStyle getStyle(String styleID){
-		for (XWPFStyle style : listStyle) {
-			if(style.getStyleId().equals(styleID))
-				return style;		
-		}
-		return null;
-	}
 
-	/**
-	 * get the styles which are related to the parameter style and their relatives
-	 * this method can be used to copy all styles from one document to another document 
-	 * @param style
-	 * @return a list of all styles which were used by this method 
-	 */
-	public List<XWPFStyle> getUsedStyleList(XWPFStyle style){
-		List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();
-		usedStyleList.add(style);
-		return getUsedStyleList(style, usedStyleList);
-	}
-	
-	/** 
-	 * get the styles which are related to parameter style
-	 * @param style
-	 * @return all Styles of the parameterList
-	 */
-	private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList){
-		String basisStyleID  = style.getBasisStyleID();
-		XWPFStyle basisStyle = getStyle(basisStyleID);
-		if((basisStyle!=null)&&(!usedStyleList.contains(basisStyle))){
-			usedStyleList.add(basisStyle);
-			getUsedStyleList(basisStyle, usedStyleList);
-		}		
-		String linkStyleID = style.getLinkStyleID();
-		XWPFStyle linkStyle = getStyle(linkStyleID);
-		if((linkStyle!=null)&&(!usedStyleList.contains(linkStyle))){
-			usedStyleList.add(linkStyle);
-			getUsedStyleList(linkStyle, usedStyleList);
-		}
-		
-		String nextStyleID = style.getNextStyleID();
-		XWPFStyle nextStyle = getStyle(nextStyleID);
-		if((nextStyle!=null)&&(!usedStyleList.contains(nextStyle))){
-			usedStyleList.add(linkStyle);
-			getUsedStyleList(linkStyle, usedStyleList);
-		}		
-		return usedStyleList;
-	}
-	
-	/**
-	 * Sets the default spelling language on ctStyles DocDefaults parameter
-	 * @param strSpellingLanguage
-	 */
-	public void setSpellingLanguage(String strSpellingLanguage) {
-		CTDocDefaults docDefaults = null;
-		CTRPr runProps = null;
-		CTLanguage lang = null;
+    /**
+     * Read document

+     */

+    @Override

+    protected void onDocumentRead() throws IOException {

+        StylesDocument stylesDoc;

+        try {

+            InputStream is = getPackagePart().getInputStream();

+            stylesDoc = StylesDocument.Factory.parse(is);
+            setStyles(stylesDoc.getStyles());
+            latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this);
+        } catch (XmlException e) {
+            throw new POIXMLException("Unable to read styles", e);
+        }
+    }
 
-		// Just making sure we use the members that have already been defined
-		if(ctStyles.isSetDocDefaults()) {
-			docDefaults = ctStyles.getDocDefaults();
-			if(docDefaults.isSetRPrDefault()) {
-				CTRPrDefault RPrDefault = docDefaults.getRPrDefault();
-				if(RPrDefault.isSetRPr()) {
-					runProps = RPrDefault.getRPr();
-					if(runProps.isSetLang())
-						lang = runProps.getLang();
-				}
-			}
-		}
+    @Override
+    protected void commit() throws IOException {
+        if (ctStyles == null) {
+            throw new IllegalStateException("Unable to write out styles that were never read in!");
+        }
+

+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);

+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));

+        Map<String, String> map = new HashMap<String, String>();

+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");

+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");

+        xmlOptions.setSaveSuggestedPrefixes(map);

+        PackagePart part = getPackagePart();
+        OutputStream out = part.getOutputStream();
+        ctStyles.save(out, xmlOptions);
+        out.close();
+    }

+

+    protected void ensureDocDefaults() {

+        if (!ctStyles.isSetDocDefaults()) {

+            ctStyles.addNewDocDefaults();

+        }

+

+        CTDocDefaults docDefaults = ctStyles.getDocDefaults();

+        if (!docDefaults.isSetPPrDefault())

+            docDefaults.addNewPPrDefault();

+        if (!docDefaults.isSetRPrDefault())

+            docDefaults.addNewRPrDefault();

+

+        CTPPrDefault pprd = docDefaults.getPPrDefault();

+        CTRPrDefault rprd = docDefaults.getRPrDefault();

+        if (!pprd.isSetPPr()) pprd.addNewPPr();

+        if (!rprd.isSetRPr()) rprd.addNewRPr();

+

+        defaultRunStyle = new XWPFDefaultRunStyle(rprd.getRPr());

+        defaultParaStyle = new XWPFDefaultParagraphStyle(pprd.getPPr());

+    }

+

+    /**

+     * Sets the ctStyles

+     *

+     * @param styles

+     */

+    @SuppressWarnings("deprecation")

+    public void setStyles(CTStyles styles) {
+        ctStyles = styles;

+

+        // Build up all the style objects

+        for (CTStyle style : ctStyles.getStyleArray()) {

+            listStyle.add(new XWPFStyle(style, this));

+        }

+        if (ctStyles.isSetDocDefaults()) {

+            CTDocDefaults docDefaults = ctStyles.getDocDefaults();
+            if (docDefaults.isSetRPrDefault() && docDefaults.getRPrDefault().isSetRPr()) {
+                defaultRunStyle = new XWPFDefaultRunStyle(
+                        docDefaults.getRPrDefault().getRPr());
+            }
+            if (docDefaults.isSetPPrDefault() && docDefaults.getPPrDefault().isSetPPr()) {
+                defaultParaStyle = new XWPFDefaultParagraphStyle(
+                        docDefaults.getPPrDefault().getPPr());
+            }
+        }
+    }
+

+    /**

+     * checks whether style with styleID exist

+     *

+     * @param styleID styleID of the Style in the style-Document

+     * @return true if style exist, false if style not exist

+     */

+    public boolean styleExist(String styleID) {

+        for (XWPFStyle style : listStyle) {

+            if (style.getStyleId().equals(styleID))

+                return true;

+        }

+        return false;

+    }

+

+    /**

+     * add a style to the document

+     *

+     * @param style

+     * @throws IOException

+     */

+    public void addStyle(XWPFStyle style) {

+        listStyle.add(style);

+        ctStyles.addNewStyle();

+        int pos = ctStyles.sizeOfStyleArray() - 1;

+        ctStyles.setStyleArray(pos, style.getCTStyle());

+    }

+

+    /**

+     * Get style by a styleID

+     *

+     * @param styleID styleID of the searched style

+     * @return style

+     */

+    public XWPFStyle getStyle(String styleID) {

+        for (XWPFStyle style : listStyle) {

+            if (style.getStyleId().equals(styleID))

+                return style;

+        }

+        return null;

+    }

+

+    public int getNumberOfStyles() {

+        return listStyle.size();

+    }

+

+    /**

+     * get the styles which are related to the parameter style and their relatives

+     * this method can be used to copy all styles from one document to another document

+     *

+     * @param style

+     * @return a list of all styles which were used by this method

+     */

+    public List<XWPFStyle> getUsedStyleList(XWPFStyle style) {

+        List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();

+        usedStyleList.add(style);

+        return getUsedStyleList(style, usedStyleList);

+    }

+

+    /**

+     * get the styles which are related to parameter style

+     *

+     * @param style

+     * @return all Styles of the parameterList

+     */

+    private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList) {

+        String basisStyleID = style.getBasisStyleID();

+        XWPFStyle basisStyle = getStyle(basisStyleID);

+        if ((basisStyle != null) && (!usedStyleList.contains(basisStyle))) {

+            usedStyleList.add(basisStyle);

+            getUsedStyleList(basisStyle, usedStyleList);

+        }

+        String linkStyleID = style.getLinkStyleID();

+        XWPFStyle linkStyle = getStyle(linkStyleID);

+        if ((linkStyle != null) && (!usedStyleList.contains(linkStyle))) {

+            usedStyleList.add(linkStyle);

+            getUsedStyleList(linkStyle, usedStyleList);

+        }

+

+        String nextStyleID = style.getNextStyleID();

+        XWPFStyle nextStyle = getStyle(nextStyleID);

+        if ((nextStyle != null) && (!usedStyleList.contains(nextStyle))) {

+            usedStyleList.add(linkStyle);

+            getUsedStyleList(linkStyle, usedStyleList);

+        }

+        return usedStyleList;

+    }

+

+    protected CTLanguage getCTLanguage() {

+        ensureDocDefaults();

+

+        CTLanguage lang = null;

+        if (defaultRunStyle.getRPr().isSetLang()) {

+            lang = defaultRunStyle.getRPr().getLang();

+        } else {

+            lang = defaultRunStyle.getRPr().addNewLang();

+        }

+

+        return lang;

+    }

+

+    /**

+     * Sets the default spelling language on ctStyles DocDefaults parameter

+     *

+     * @param strSpellingLanguage

+     */

+    public void setSpellingLanguage(String strSpellingLanguage) {

+        CTLanguage lang = getCTLanguage();
+        lang.setVal(strSpellingLanguage);

+        lang.setBidi(strSpellingLanguage);

+    }

+

+    /**

+     * Sets the default East Asia spelling language on ctStyles DocDefaults parameter

+     *

+     * @param strEastAsia

+     */

+    public void setEastAsia(String strEastAsia) {

+        CTLanguage lang = getCTLanguage();
+        lang.setEastAsia(strEastAsia);
+    }
 
-		if(docDefaults == null)
-			docDefaults = ctStyles.addNewDocDefaults();
-		if(runProps == null)
-			runProps = docDefaults.addNewRPrDefault().addNewRPr();
-		if(lang == null)
-			lang = runProps.addNewLang();
+    /**

+     * Sets the default font on ctStyles DocDefaults parameter

+     * TODO Replace this with specific setters for each type, possibly

+     * on XWPFDefaultRunStyle

+     */

+    public void setDefaultFonts(CTFonts fonts) {

+        ensureDocDefaults();

+

+        CTRPr runProps = defaultRunStyle.getRPr();

+        runProps.setRFonts(fonts);

+    }

 
-		lang.setVal(strSpellingLanguage);
-		lang.setBidi(strSpellingLanguage);
-	}
+    /**
+     * get the style with the same name

+     * if this style is not existing, return null

+     */

+    public XWPFStyle getStyleWithSameName(XWPFStyle style) {

+        for (XWPFStyle ownStyle : listStyle) {

+            if (ownStyle.hasSameName(style)) {

+                return ownStyle;

+            }

+        }

+        return null;

+    }

 
-	/**
-	 * Sets the default East Asia spelling language on ctStyles DocDefaults parameter
-	 * @param strEastAsia
-	 */
-	public void setEastAsia(String strEastAsia) {
-		CTDocDefaults docDefaults = null;
-		CTRPr runProps = null;
-		CTLanguage lang = null;
+    /**
+     * Get the default style which applies text runs in the document
+     */
+    public XWPFDefaultRunStyle getDefaultRunStyle() {
+        ensureDocDefaults();
+        return defaultRunStyle;
+    }
 
-		// Just making sure we use the members that have already been defined
-		if(ctStyles.isSetDocDefaults()) {
-			docDefaults = ctStyles.getDocDefaults();
-			if(docDefaults.isSetRPrDefault()) {
-				CTRPrDefault RPrDefault = docDefaults.getRPrDefault();
-				if(RPrDefault.isSetRPr()) {
-					runProps = RPrDefault.getRPr();
-					if(runProps.isSetLang())
-						lang = runProps.getLang();
-				}
-			}
-		}
+    /**
+     * Get the default paragraph style which applies to the document
+     */
+    public XWPFDefaultParagraphStyle getDefaultParagraphStyle() {
+        ensureDocDefaults();
+        return defaultParaStyle;
+    }
 
-		if(docDefaults == null)
-			docDefaults = ctStyles.addNewDocDefaults();
-		if(runProps == null)
-			runProps = docDefaults.addNewRPrDefault().addNewRPr();
-		if(lang == null)
-			lang = runProps.addNewLang();
-
-		lang.setEastAsia(strEastAsia);
-	}
-
-	/**
-	 * Sets the default font on ctStyles DocDefaults parameter
-	 * @param fonts
-	 */
-	public void setDefaultFonts(CTFonts fonts) {
-		CTDocDefaults docDefaults = null;
-		CTRPr runProps = null;
-
-		// Just making sure we use the members that have already been defined
-		if(ctStyles.isSetDocDefaults()) {
-			docDefaults = ctStyles.getDocDefaults();
-			if(docDefaults.isSetRPrDefault()) {
-				CTRPrDefault RPrDefault = docDefaults.getRPrDefault();
-				if(RPrDefault.isSetRPr()) {
-					runProps = RPrDefault.getRPr();
-				}
-			}
-		}
-
-		if(docDefaults == null)
-			docDefaults = ctStyles.addNewDocDefaults();
-		if(runProps == null)
-			runProps = docDefaults.addNewRPrDefault().addNewRPr();
-
-		runProps.setRFonts(fonts);
-	}
-	
-	
-	/**
-	 * get latentstyles
-	 */
-	public XWPFLatentStyles getLatentStyles() {
-		return latentStyles;
-	}
-	
-	/**
-	 * get the style with the same name
-	 * if this style is not existing, return null
-	 */
-	public XWPFStyle getStyleWithSameName(XWPFStyle style){
-		for (XWPFStyle ownStyle : listStyle) {
-			if(ownStyle.hasSameName(style)){
-				return ownStyle;
-			}	
-		}
-		return null;
-		
-	}
-}//end class
+    /**
+     * Get the definition of all the Latent Styles
+     */
+    public XWPFLatentStyles getLatentStyles() {
+        return latentStyles;
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
index 643d28f..1f4fd2b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
@@ -44,19 +44,10 @@
  * of paragraphs (and other block-level content) arranged in rows and columns.</p>
  */
 public class XWPFTable implements IBodyElement, ISDTContents {
-    protected StringBuffer text = new StringBuffer();
-    private CTTbl ctTbl;
-    protected List<XWPFTableRow> tableRows;
-    protected List<String> styleIDs;
-
-    // Create a map from this XWPF-level enum to the STBorder.Enum values
-    public static enum XWPFBorderType { NIL, NONE, SINGLE, THICK, DOUBLE, DOTTED, DASHED, DOT_DASH };
     private static EnumMap<XWPFBorderType, STBorder.Enum> xwpfBorderTypeMap;
     // Create a map from the STBorder.Enum values to the XWPF-level enums
     private static HashMap<Integer, XWPFBorderType> stBorderTypeMap;
 
-    protected IBody part;
-
     static {
         // populate enum maps
         xwpfBorderTypeMap = new EnumMap<XWPFBorderType, STBorder.Enum>(XWPFBorderType.class);
@@ -77,9 +68,17 @@
         stBorderTypeMap.put(STBorder.INT_DOUBLE, XWPFBorderType.DOUBLE);
         stBorderTypeMap.put(STBorder.INT_DOTTED, XWPFBorderType.DOTTED);
         stBorderTypeMap.put(STBorder.INT_DASHED, XWPFBorderType.DASHED);
-        stBorderTypeMap.put(STBorder.INT_DOT_DASH, XWPFBorderType.DOT_DASH); 
+        stBorderTypeMap.put(STBorder.INT_DOT_DASH, XWPFBorderType.DOT_DASH);
     }
-    
+
+    protected StringBuffer text = new StringBuffer();
+    protected List<XWPFTableRow> tableRows;
+
+    ;
+    protected List<String> styleIDs;
+    protected IBody part;
+    private CTTbl ctTbl;
+
     public XWPFTable(CTTbl table, IBody part, int row, int col) {
         this(table, part);
 
@@ -94,7 +93,7 @@
     }
 
     @SuppressWarnings("deprecation")
-    public XWPFTable(CTTbl table, IBody part){
+    public XWPFTable(CTTbl table, IBody part) {
         this.part = part;
         this.ctTbl = table;
 
@@ -163,9 +162,9 @@
      * Convenience method to extract text in cells.  This
      * does not extract text recursively in cells, and it does not
      * currently include text in SDT (form) components.
-     * <p>
+     * <p/>
      * To get all text within a table, see XWPFWordExtractor's appendTableText
-     * as an example. 
+     * as an example.
      *
      * @return text
      */
@@ -216,6 +215,13 @@
         return null;
     }
 
+    /**
+     * @return width value
+     */
+    public int getWidth() {
+        CTTblPr tblPr = getTrPr();
+        return tblPr.isSetTblW() ? tblPr.getTblW().getW().intValue() : -1;
+    }
 
     /**
      * @param width
@@ -227,14 +233,6 @@
     }
 
     /**
-     * @return width value
-     */
-    public int getWidth() {
-        CTTblPr tblPr = getTrPr();
-        return tblPr.isSetTblW() ? tblPr.getTblW().getW().intValue() : -1;
-    }
-
-    /**
      * @return number of rows in table
      */
     public int getNumberOfRows() {
@@ -253,12 +251,13 @@
             }
         }
     }
-    
+
     /**
      * get the StyleID of the table
-     * @return	style-ID of the table
+     *
+     * @return style-ID of the table
      */
-    public String getStyleID(){
+    public String getStyleID() {
         String styleId = null;
         CTTblPr tblPr = ctTbl.getTblPr();
         if (tblPr != null) {
@@ -273,6 +272,7 @@
     /**
      * Set the table style. If the style is not defined in the document, MS Word
      * will set the table style to "Normal".
+     *
      * @param styleName - the style name to apply to this table
      */
     public void setStyleID(String styleName) {
@@ -523,24 +523,25 @@
 
     /**
      * add a new Row to the table
-     * 
-     * @param row	the row which should be added
+     *
+     * @param row the row which should be added
      */
-    public void addRow(XWPFTableRow row){
+    public void addRow(XWPFTableRow row) {
         ctTbl.addNewTr();
-        ctTbl.setTrArray(getNumberOfRows()-1, row.getCtRow());
+        ctTbl.setTrArray(getNumberOfRows() - 1, row.getCtRow());
         tableRows.add(row);
     }
 
     /**
      * add a new Row to the table
      * at position pos
-     * @param row	the row which should be added
+     *
+     * @param row the row which should be added
      */
-    public boolean addRow(XWPFTableRow row, int pos){
-        if(pos >= 0 && pos <= tableRows.size()){
+    public boolean addRow(XWPFTableRow row, int pos) {
+        if (pos >= 0 && pos <= tableRows.size()) {
             ctTbl.insertNewTr(pos);
-            ctTbl.setTrArray(pos,row.getCtRow());
+            ctTbl.setTrArray(pos, row.getCtRow());
             tableRows.add(pos, row);
             return true;
         }
@@ -548,12 +549,13 @@
     }
 
     /**
-     * inserts a new tablerow 
+     * inserts a new tablerow
+     *
      * @param pos
-     * @return  the inserted row
+     * @return the inserted row
      */
-    public XWPFTableRow insertNewTableRow(int pos){
-        if(pos >= 0 && pos <= tableRows.size()){
+    public XWPFTableRow insertNewTableRow(int pos) {
+        if (pos >= 0 && pos <= tableRows.size()) {
             CTRow row = ctTbl.insertNewTr(pos);
             XWPFTableRow tableRow = new XWPFTableRow(row, this);
             tableRows.add(pos, tableRow);
@@ -562,10 +564,10 @@
         return null;
     }
 
-
     /**
      * Remove a row at position pos from the table
-     * @param pos	position the Row in the Table
+     *
+     * @param pos position the Row in the Table
      */
     public boolean removeRow(int pos) throws IndexOutOfBoundsException {
         if (pos >= 0 && pos < tableRows.size()) {
@@ -582,9 +584,9 @@
         return tableRows;
     }
 
-
     /**
      * returns the type of the BodyElement Table
+     *
      * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
      */
     public BodyElementType getElementType() {
@@ -597,10 +599,11 @@
 
     /**
      * returns the part of the bodyElement
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
      */
     public POIXMLDocumentPart getPart() {
-        if(part != null){
+        if (part != null) {
             return part.getPart();
         }
         return null;
@@ -608,6 +611,7 @@
 
     /**
      * returns the partType of the bodyPart which owns the bodyElement
+     *
      * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
      */
     public BodyType getPartType() {
@@ -619,9 +623,14 @@
      * if this row is not existing in the table null will be returned
      */
     public XWPFTableRow getRow(CTRow row) {
-        for(int i=0; i<getRows().size(); i++){
-            if(getRows().get(i).getCtRow()== row) return getRow(i); 
+        for (int i = 0; i < getRows().size(); i++) {
+            if (getRows().get(i).getCtRow() == row) return getRow(i);
         }
         return null;
     }
+
+    // Create a map from this XWPF-level enum to the STBorder.Enum values
+    public static enum XWPFBorderType {
+        NIL, NONE, SINGLE, THICK, DOUBLE, DOTTED, DASHED, DOT_DASH
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
index c1f0d4f..cc6ac3a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
@@ -37,23 +37,15 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STShd;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
-
-/**
- * Represents a Cell within a {@link XWPFTable}. The
- *  Cell is the thing that holds the actual content (paragraphs etc)
- */
-public class XWPFTableCell implements IBody, ICell {
-    private final CTTc ctTc;
-    protected List<XWPFParagraph> paragraphs = null;
-    protected List<XWPFTable> tables = null;
-    protected List<IBodyElement> bodyElements = null;
-    protected IBody part;
-    private XWPFTableRow tableRow = null;
-    // Create a map from this XWPF-level enum to the STVerticalJc.Enum values
-    public static enum XWPFVertAlign { TOP, CENTER, BOTH, BOTTOM };
-    private static EnumMap<XWPFVertAlign, STVerticalJc.Enum> alignMap;
-    // Create a map from the STVerticalJc.Enum values to the XWPF-level enums
-    private static HashMap<Integer, XWPFVertAlign> stVertAlignTypeMap;
+

+/**

+ * Represents a Cell within a {@link XWPFTable}. The

+ * Cell is the thing that holds the actual content (paragraphs etc)

+ */

+public class XWPFTableCell implements IBody, ICell {

+    private static EnumMap<XWPFVertAlign, STVerticalJc.Enum> alignMap;

+    // Create a map from the STVerticalJc.Enum values to the XWPF-level enums

+    private static HashMap<Integer, XWPFVertAlign> stVertAlignTypeMap;

 
     static {
         // populate enum maps
@@ -68,337 +60,343 @@
         stVertAlignTypeMap.put(STVerticalJc.INT_CENTER, XWPFVertAlign.CENTER);
         stVertAlignTypeMap.put(STVerticalJc.INT_BOTH, XWPFVertAlign.BOTH);
         stVertAlignTypeMap.put(STVerticalJc.INT_BOTTOM, XWPFVertAlign.BOTTOM);
-
-    }
-
-    /**
-     * If a table cell does not include at least one block-level element, then this document shall be considered corrupt
-     */
+

+    }

+

+    private final CTTc ctTc;

+    protected List<XWPFParagraph> paragraphs = null;

+    protected List<XWPFTable> tables = null;

+    protected List<IBodyElement> bodyElements = null;

+

+    ;

+    protected IBody part;

+    private XWPFTableRow tableRow = null;

+

+    /**

+     * If a table cell does not include at least one block-level element, then this document shall be considered corrupt

+     */

     public XWPFTableCell(CTTc cell, XWPFTableRow tableRow, IBody part) {
         this.ctTc = cell;
-        this.part = part;
-        this.tableRow = tableRow;
-        // NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt.
-        if(cell.sizeOfPArray()<1)
-            cell.addNewP();
-        bodyElements = new ArrayList<IBodyElement>();
-        paragraphs = new ArrayList<XWPFParagraph>();
+        this.part = part;

+        this.tableRow = tableRow;

+        // NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt.

+        if (cell.sizeOfPArray() < 1)

+            cell.addNewP();

+        bodyElements = new ArrayList<IBodyElement>();

+        paragraphs = new ArrayList<XWPFParagraph>();

         tables = new ArrayList<XWPFTable>();
 
         XmlCursor cursor = ctTc.newCursor();
         cursor.selectPath("./*");
-        while (cursor.toNextSelection()) {
-            XmlObject o = cursor.getObject();
-            if (o instanceof CTP) {
-                XWPFParagraph p = new XWPFParagraph((CTP)o, this);
-                paragraphs.add(p);
-                bodyElements.add(p);
-            }
-            if (o instanceof CTTbl) {
-                XWPFTable t = new XWPFTable((CTTbl)o, this);
-                tables.add(t);
-                bodyElements.add(t);
-            }
-            if (o instanceof CTSdtBlock){
-               XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
-               bodyElements.add(c);
-            }
-            if (o instanceof CTSdtRun){
-               XWPFSDT c = new XWPFSDT((CTSdtRun)o, this);
-               System.out.println(c.getContent().getText());
-               bodyElements.add(c);
-            }
-        }
-        cursor.dispose();
+        while (cursor.toNextSelection()) {

+            XmlObject o = cursor.getObject();

+            if (o instanceof CTP) {

+                XWPFParagraph p = new XWPFParagraph((CTP) o, this);

+                paragraphs.add(p);

+                bodyElements.add(p);

+            }

+            if (o instanceof CTTbl) {

+                XWPFTable t = new XWPFTable((CTTbl) o, this);

+                tables.add(t);

+                bodyElements.add(t);

+            }

+            if (o instanceof CTSdtBlock) {

+                XWPFSDT c = new XWPFSDT((CTSdtBlock) o, this);

+                bodyElements.add(c);

+            }

+            if (o instanceof CTSdtRun) {

+                XWPFSDT c = new XWPFSDT((CTSdtRun) o, this);

+                System.out.println(c.getContent().getText());

+                bodyElements.add(c);

+            }

+        }

+        cursor.dispose();

+    }

+

+    @Internal

+    public CTTc getCTTc() {

+        return ctTc;

     }
-
-
-    @Internal
-    public CTTc getCTTc() {
-        return ctTc;
-    }
-
-    /**
-     * returns an Iterator with paragraphs and tables
-     * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
-     */
-    public List<IBodyElement> getBodyElements(){
-      return Collections.unmodifiableList(bodyElements);
-    }
-    
-    public void setParagraph(XWPFParagraph p) {
-        if (ctTc.sizeOfPArray() == 0) {
-            ctTc.addNewP();
+

+    /**

+     * returns an Iterator with paragraphs and tables

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()

+     */

+    public List<IBodyElement> getBodyElements() {

+        return Collections.unmodifiableList(bodyElements);

+    }

+

+    public void setParagraph(XWPFParagraph p) {

+        if (ctTc.sizeOfPArray() == 0) {

+            ctTc.addNewP();

         }
         ctTc.setPArray(0, p.getCTP());
     }
 
-    /**
-     * returns a list of paragraphs
-     */
-    public List<XWPFParagraph> getParagraphs(){
-    		return paragraphs;
-    }
-    
-    /**
-     * Add a Paragraph to this Table Cell
-     * @return The paragraph which was added
-     */
-    public XWPFParagraph addParagraph() {
-       XWPFParagraph p = new XWPFParagraph(ctTc.addNewP(), this);
-       addParagraph(p);
-       return p;
-    }
-    
-    /**
-     * add a Paragraph to this TableCell
-     * @param p the paragaph which has to be added
-     */
-    public void addParagraph(XWPFParagraph p){
-    	paragraphs.add(p);
-    }
-    
-    /**
-     * removes a paragraph of this tablecell
-     * @param pos
-     */
-    public void removeParagraph(int pos){
-    	paragraphs.remove(pos);
-    	ctTc.removeP(pos);
-    }
-    
-	/**
-	 * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this table
-	 * the method will return this paragraph
-	 * if there is no corresponding {@link XWPFParagraph} the method will return null 
-	 * @param p is instance of CTP and is searching for an XWPFParagraph
-	 * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this table
-	 * 		   XWPFParagraph with the correspondig CTP p
-	 */
-    public XWPFParagraph getParagraph(CTP p){
-	for (XWPFParagraph paragraph : paragraphs) {
-	    if(p.equals(paragraph.getCTP())){
-		return paragraph;
-	    }
-	}
-	return null;
-    }	
-    
-    public void setText(String text) {
-        CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);
-        XWPFParagraph par = new XWPFParagraph(ctP, this);
-        par.createRun().setText(text);
-    }
-    
-    public XWPFTableRow getTableRow(){
-    	return tableRow;
-    }
-    
-    /**
-     * Set cell color. This sets some associated values; for finer control
-     * you may want to access these elements individually.
-     * @param rgbStr - the desired cell color, in the hex form "RRGGBB".
-     */
-    public void setColor(String rgbStr) {
-        CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
-        CTShd ctshd = tcpr.isSetShd() ? tcpr.getShd() : tcpr.addNewShd();
-        ctshd.setColor("auto");
-        ctshd.setVal(STShd.CLEAR);
-        ctshd.setFill(rgbStr);
-    }
-
-    /**
-     * Get cell color. Note that this method only returns the "fill" value.
-     * @return RGB string of cell color
-     */
-    public String getColor() {
-	String color = null;
-	CTTcPr tcpr = ctTc.getTcPr();
-	if (tcpr != null) {
-	    CTShd ctshd = tcpr.getShd();
-	    if (ctshd != null) {
-		color = ctshd.xgetFill().getStringValue();
-	    }
-	}
-	return color;
-    }
-
-    /**
-     * Set the vertical alignment of the cell.
-     * @param vAlign - the desired alignment enum value
-     */
-    public void setVerticalAlignment(XWPFVertAlign vAlign) {
-        CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
-    	CTVerticalJc va = tcpr.addNewVAlign();
-    	va.setVal(alignMap.get(vAlign));
-    }
-
-    /**
-     * Get the vertical alignment of the cell.
-     * @return the cell alignment enum value
-     */
-    public XWPFVertAlign getVerticalAlignment() {
-	XWPFVertAlign vAlign = null;
-	CTTcPr tcpr = ctTc.getTcPr();
-	if (ctTc != null) {
-	    CTVerticalJc va = tcpr.getVAlign();
-	    vAlign = stVertAlignTypeMap.get(va.getVal().intValue());
-	}
-	return vAlign;
-    }
-
-    /**
-     * add a new paragraph at position of the cursor
-     * @param cursor
-     * @return the inserted paragraph
-     */
-    public XWPFParagraph insertNewParagraph(XmlCursor cursor){
-	if(!isCursorInTableCell(cursor)) {
-	    return null;
-	}
-
-	String uri = CTP.type.getName().getNamespaceURI();
-	String localPart = "p";
-	cursor.beginElement(localPart,uri);
-	cursor.toParent();
-	CTP p = (CTP)cursor.getObject();
-	XWPFParagraph newP = new XWPFParagraph(p, this);
-	XmlObject o = null;
-	while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
-	    o = cursor.getObject();
-	}
-	if((!(o instanceof CTP)) || (CTP)o == p){
-	    paragraphs.add(0, newP);
-	}
-	else{
-	    int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
-	    paragraphs.add(pos,newP);
-	}
-	int i=0;
-	cursor.toCursor(p.newCursor());
-	while(cursor.toPrevSibling()){
-	    o =cursor.getObject();
-	    if(o instanceof CTP || o instanceof CTTbl)
-		i++;
-	}
-	bodyElements.add(i, newP);
-	cursor.toCursor(p.newCursor());
-	cursor.toEndToken();
-	return newP;
-    }
-
-    public XWPFTable insertNewTbl(XmlCursor cursor) {
-	if(isCursorInTableCell(cursor)){
-	    String uri = CTTbl.type.getName().getNamespaceURI();
-	    String localPart = "tbl";
-	    cursor.beginElement(localPart,uri);
-	    cursor.toParent();
-	    CTTbl t = (CTTbl)cursor.getObject();
-	    XWPFTable newT = new XWPFTable(t, this);
-	    cursor.removeXmlContents();
-	    XmlObject o = null;
-	    while(!(o instanceof CTTbl)&&(cursor.toPrevSibling())){
-		o = cursor.getObject();
-	    }
-	    if(!(o instanceof CTTbl)){
-		tables.add(0, newT);
-	    }
-	    else{
-		int pos = tables.indexOf(getTable((CTTbl)o))+1;
-		tables.add(pos,newT);
-	    }
-	    int i=0;
-	    cursor = t.newCursor();
-	    while(cursor.toPrevSibling()){
-		o =cursor.getObject();
-		if(o instanceof CTP || o instanceof CTTbl)
-		    i++;
-	    }
-	    bodyElements.add(i, newT);
-	    cursor = t.newCursor();
-	    cursor.toEndToken();
-	    return newT;
-	}
-	return null;
-    }
-
-    /**
-     * verifies that cursor is on the right position
-     */
-    private boolean isCursorInTableCell(XmlCursor cursor) {
-	XmlCursor verify = cursor.newCursor();
-	verify.toParent();
-	if(verify.getObject() == this.ctTc){
-	    return true;
-	}
-	return false;
-    }
-
-
-
-    /**
-     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)
-     */
-    public XWPFParagraph getParagraphArray(int pos) {
-	if(pos > 0 && pos < paragraphs.size()){
-	    return paragraphs.get(pos);
-	}
-	return null;
-    }
-
-    /**
-     * get the to which the TableCell belongs
-     * 
-     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
-     */
-    public POIXMLDocumentPart getPart() {
-        return tableRow.getTable().getPart();
-    }
-
-    /** 
-     * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
-     */
-    public BodyType getPartType() {
-	return BodyType.TABLECELL;
-    }
-
-
-    /**
-     * get a table by its CTTbl-Object
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
-     */
-    public XWPFTable getTable(CTTbl ctTable) {
-	for(int i=0; i<tables.size(); i++){
-	    if(getTables().get(i).getCTTbl() == ctTable) return getTables().get(i); 
-	}
-	return null;
-    }
-
-
-    /** 
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
-     */
-    public XWPFTable getTableArray(int pos) {
-	if(pos > 0 && pos < tables.size()){
-	    return tables.get(pos);
-	}
-	return null;
-    }
-
-
-    /** 
-     * @see org.apache.poi.xwpf.usermodel.IBody#getTables()
-     */
-    public List<XWPFTable> getTables() {
-	return Collections.unmodifiableList(tables);
-    }
-
-
-    /**
-     * inserts an existing XWPFTable to the arrays bodyElements and tables
-     * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable)
-     */
-    @SuppressWarnings("deprecation")
+    /**

+     * returns a list of paragraphs

+     */

+    public List<XWPFParagraph> getParagraphs() {

+        return paragraphs;

+    }

+

+    /**

+     * Add a Paragraph to this Table Cell

+     *

+     * @return The paragraph which was added

+     */

+    public XWPFParagraph addParagraph() {

+        XWPFParagraph p = new XWPFParagraph(ctTc.addNewP(), this);

+        addParagraph(p);

+        return p;

+    }

+

+    /**

+     * add a Paragraph to this TableCell

+     *

+     * @param p the paragaph which has to be added

+     */

+    public void addParagraph(XWPFParagraph p) {

+        paragraphs.add(p);

+    }

+

+    /**

+     * removes a paragraph of this tablecell

+     *

+     * @param pos

+     */

+    public void removeParagraph(int pos) {

+        paragraphs.remove(pos);

+        ctTc.removeP(pos);

+    }

+

+    /**

+     * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this table

+     * the method will return this paragraph

+     * if there is no corresponding {@link XWPFParagraph} the method will return null

+     *

+     * @param p is instance of CTP and is searching for an XWPFParagraph

+     * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this table

+     * XWPFParagraph with the correspondig CTP p

+     */

+    public XWPFParagraph getParagraph(CTP p) {

+        for (XWPFParagraph paragraph : paragraphs) {

+            if (p.equals(paragraph.getCTP())) {

+                return paragraph;

+            }

+        }

+        return null;

+    }

+

+    public XWPFTableRow getTableRow() {

+        return tableRow;

+    }

+

+    /**

+     * Get cell color. Note that this method only returns the "fill" value.

+     *

+     * @return RGB string of cell color

+     */

+    public String getColor() {

+        String color = null;

+        CTTcPr tcpr = ctTc.getTcPr();

+        if (tcpr != null) {

+            CTShd ctshd = tcpr.getShd();

+            if (ctshd != null) {

+                color = ctshd.xgetFill().getStringValue();

+            }

+        }

+        return color;

+    }

+

+    /**

+     * Set cell color. This sets some associated values; for finer control

+     * you may want to access these elements individually.

+     *

+     * @param rgbStr - the desired cell color, in the hex form "RRGGBB".

+     */

+    public void setColor(String rgbStr) {

+        CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();

+        CTShd ctshd = tcpr.isSetShd() ? tcpr.getShd() : tcpr.addNewShd();

+        ctshd.setColor("auto");

+        ctshd.setVal(STShd.CLEAR);

+        ctshd.setFill(rgbStr);

+    }

+

+    /**

+     * Get the vertical alignment of the cell.

+     *

+     * @return the cell alignment enum value

+     */

+    public XWPFVertAlign getVerticalAlignment() {

+        XWPFVertAlign vAlign = null;

+        CTTcPr tcpr = ctTc.getTcPr();

+        if (ctTc != null) {

+            CTVerticalJc va = tcpr.getVAlign();

+            vAlign = stVertAlignTypeMap.get(va.getVal().intValue());

+        }

+        return vAlign;

+    }

+

+    /**

+     * Set the vertical alignment of the cell.

+     *

+     * @param vAlign - the desired alignment enum value

+     */

+    public void setVerticalAlignment(XWPFVertAlign vAlign) {

+        CTTcPr tcpr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();

+        CTVerticalJc va = tcpr.addNewVAlign();

+        va.setVal(alignMap.get(vAlign));

+    }

+

+    /**

+     * add a new paragraph at position of the cursor

+     *

+     * @param cursor

+     * @return the inserted paragraph

+     */

+    public XWPFParagraph insertNewParagraph(XmlCursor cursor) {

+        if (!isCursorInTableCell(cursor)) {

+            return null;

+        }

+

+        String uri = CTP.type.getName().getNamespaceURI();

+        String localPart = "p";

+        cursor.beginElement(localPart, uri);

+        cursor.toParent();

+        CTP p = (CTP) cursor.getObject();

+        XWPFParagraph newP = new XWPFParagraph(p, this);

+        XmlObject o = null;

+        while (!(o instanceof CTP) && (cursor.toPrevSibling())) {

+            o = cursor.getObject();

+        }

+        if ((!(o instanceof CTP)) || (CTP) o == p) {

+            paragraphs.add(0, newP);

+        } else {

+            int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;

+            paragraphs.add(pos, newP);

+        }

+        int i = 0;

+        cursor.toCursor(p.newCursor());

+        while (cursor.toPrevSibling()) {

+            o = cursor.getObject();

+            if (o instanceof CTP || o instanceof CTTbl)

+                i++;

+        }

+        bodyElements.add(i, newP);

+        cursor.toCursor(p.newCursor());

+        cursor.toEndToken();

+        return newP;

+    }

+

+    public XWPFTable insertNewTbl(XmlCursor cursor) {

+        if (isCursorInTableCell(cursor)) {

+            String uri = CTTbl.type.getName().getNamespaceURI();

+            String localPart = "tbl";

+            cursor.beginElement(localPart, uri);

+            cursor.toParent();

+            CTTbl t = (CTTbl) cursor.getObject();

+            XWPFTable newT = new XWPFTable(t, this);

+            cursor.removeXmlContents();

+            XmlObject o = null;

+            while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) {

+                o = cursor.getObject();

+            }

+            if (!(o instanceof CTTbl)) {

+                tables.add(0, newT);

+            } else {

+                int pos = tables.indexOf(getTable((CTTbl) o)) + 1;

+                tables.add(pos, newT);

+            }

+            int i = 0;

+            cursor = t.newCursor();

+            while (cursor.toPrevSibling()) {

+                o = cursor.getObject();

+                if (o instanceof CTP || o instanceof CTTbl)

+                    i++;

+            }

+            bodyElements.add(i, newT);

+            cursor = t.newCursor();

+            cursor.toEndToken();

+            return newT;

+        }

+        return null;

+    }

+

+    /**

+     * verifies that cursor is on the right position

+     */

+    private boolean isCursorInTableCell(XmlCursor cursor) {

+        XmlCursor verify = cursor.newCursor();

+        verify.toParent();

+        if (verify.getObject() == this.ctTc) {

+            return true;

+        }

+        return false;

+    }

+

+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)

+     */

+    public XWPFParagraph getParagraphArray(int pos) {

+        if (pos > 0 && pos < paragraphs.size()) {

+            return paragraphs.get(pos);

+        }

+        return null;

+    }

+

+    /**

+     * get the to which the TableCell belongs

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()

+     */

+    public POIXMLDocumentPart getPart() {

+        return tableRow.getTable().getPart();

+    }

+

+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()

+     */

+    public BodyType getPartType() {

+        return BodyType.TABLECELL;

+    }

+

+    /**

+     * get a table by its CTTbl-Object

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)

+     */

+    public XWPFTable getTable(CTTbl ctTable) {

+        for (int i = 0; i < tables.size(); i++) {

+            if (getTables().get(i).getCTTbl() == ctTable) return getTables().get(i);

+        }

+        return null;

+    }

+

+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)

+     */

+    public XWPFTable getTableArray(int pos) {

+        if (pos > 0 && pos < tables.size()) {

+            return tables.get(pos);

+        }

+        return null;

+    }

+

+    /**

+     * @see org.apache.poi.xwpf.usermodel.IBody#getTables()

+     */

+    public List<XWPFTable> getTables() {

+        return Collections.unmodifiableList(tables);

+    }

+

+    /**

+     * inserts an existing XWPFTable to the arrays bodyElements and tables

+     *

+     * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable)

+     */

+    @SuppressWarnings("deprecation")

     public void insertTable(int pos, XWPFTable table) {
         bodyElements.add(pos, table);
         int i = 0;
@@ -408,90 +406,101 @@
             }
             i++;
         }
-        tables.add(i, table);
-    }
-
-    public String getText(){
-	StringBuffer text = new StringBuffer();
-	for (XWPFParagraph p : paragraphs) {
-	    text.append(p.getText());
-	}
-	return text.toString();
+        tables.add(i, table);

+    }

+

+    public String getText() {

+        StringBuffer text = new StringBuffer();

+        for (XWPFParagraph p : paragraphs) {

+            text.append(p.getText());

+        }

+        return text.toString();

+    }

+

+    public void setText(String text) {

+        CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);

+        XWPFParagraph par = new XWPFParagraph(ctP, this);

+        par.createRun().setText(text);

+    }

+

+    /**

+     * extracts all text recursively through embedded tables and embedded SDTs

+     */

+    public String getTextRecursively() {

+

+        StringBuffer text = new StringBuffer();

+        for (int i = 0; i < bodyElements.size(); i++) {

+            boolean isLast = (i == bodyElements.size() - 1) ? true : false;

+            appendBodyElementText(text, bodyElements.get(i), isLast);

+        }

+

+        return text.toString();

+    }

+

+    private void appendBodyElementText(StringBuffer text, IBodyElement e, boolean isLast) {

+        if (e instanceof XWPFParagraph) {

+            text.append(((XWPFParagraph) e).getText());

+            if (isLast == false) {

+                text.append('\t');

+            }

+        } else if (e instanceof XWPFTable) {

+            XWPFTable eTable = (XWPFTable) e;

+            for (XWPFTableRow row : eTable.getRows()) {

+                for (XWPFTableCell cell : row.getTableCells()) {

+                    List<IBodyElement> localBodyElements = cell.getBodyElements();

+                    for (int i = 0; i < localBodyElements.size(); i++) {

+                        boolean localIsLast = (i == localBodyElements.size() - 1) ? true : false;

+                        appendBodyElementText(text, localBodyElements.get(i), localIsLast);

+                    }

+                }

+            }

+

+            if (isLast == false) {

+                text.append('\n');

+            }

+        } else if (e instanceof XWPFSDT) {

+            text.append(((XWPFSDT) e).getContent().getText());

+            if (isLast == false) {

+                text.append('\t');

+            }

+        }

     }
 
     /**
-     * extracts all text recursively through embedded tables and embedded SDTs
-     */
-    public String getTextRecursively(){
-
-        StringBuffer text = new StringBuffer();
-        for (int i = 0; i < bodyElements.size(); i++){
-            boolean isLast = (i== bodyElements.size()-1)? true : false;
-            appendBodyElementText(text, bodyElements.get(i), isLast);
-        }
-
-        return text.toString();
-    }
-
-    private void appendBodyElementText(StringBuffer text, IBodyElement e, boolean isLast){
-        if (e instanceof XWPFParagraph){
-            text.append(((XWPFParagraph)e).getText());
-            if (isLast == false){
-                text.append('\t');
-            }
-        } else if (e instanceof XWPFTable){
-            XWPFTable eTable = (XWPFTable)e;
-            for (XWPFTableRow row : eTable.getRows()){
-                for (XWPFTableCell cell : row.getTableCells()){
-                    List<IBodyElement> localBodyElements = cell.getBodyElements();
-                    for (int i = 0; i < localBodyElements.size(); i++){
-                        boolean localIsLast = (i== localBodyElements.size()-1)? true : false;
-                        appendBodyElementText(text, localBodyElements.get(i), localIsLast);
-                    }
-                }
-            }
-
-            if (isLast == false){
-                text.append('\n');
-            }
-        } else if (e instanceof XWPFSDT){
-            text.append(((XWPFSDT)e).getContent().getText());
-            if (isLast == false){
-                text.append('\t');
-            }
-        }
-    }
-
-    /**
-     * get the TableCell which belongs to the TableCell
-     */
-    public XWPFTableCell getTableCell(CTTc cell) {
-	XmlCursor cursor = cell.newCursor();
-	cursor.toParent();
-	XmlObject o = cursor.getObject();
-	if(!(o instanceof CTRow)){
-	    return null;
-	}
-	CTRow row = (CTRow)o;
-	cursor.toParent();
-	o = cursor.getObject();
-	cursor.dispose();
-	if(! (o instanceof CTTbl)){
-	    return null;
-	}
-	CTTbl tbl = (CTTbl) o;
-	XWPFTable table = getTable(tbl);
-	if(table == null){
-	    return null;
-	}
-	XWPFTableRow tableRow = table.getRow(row);
-	if (tableRow == null) {
-	    return null;
-	}
-	return tableRow.getTableCell(cell);
-    }
-
-    public XWPFDocument getXWPFDocument() {
-	return part.getXWPFDocument();
-    }
-}
+     * get the TableCell which belongs to the TableCell

+     */

+    public XWPFTableCell getTableCell(CTTc cell) {

+        XmlCursor cursor = cell.newCursor();

+        cursor.toParent();

+        XmlObject o = cursor.getObject();

+        if (!(o instanceof CTRow)) {

+            return null;

+        }

+        CTRow row = (CTRow) o;

+        cursor.toParent();

+        o = cursor.getObject();

+        cursor.dispose();

+        if (!(o instanceof CTTbl)) {

+            return null;

+        }

+        CTTbl tbl = (CTTbl) o;

+        XWPFTable table = getTable(tbl);

+        if (table == null) {

+            return null;

+        }

+        XWPFTableRow tableRow = table.getRow(row);

+        if (tableRow == null) {

+            return null;

+        }

+        return tableRow.getTableCell(cell);

+    }

+

+    public XWPFDocument getXWPFDocument() {

+        return part.getXWPFDocument();

+    }

+

+    // Create a map from this XWPF-level enum to the STVerticalJc.Enum values

+    public static enum XWPFVertAlign {

+        TOP, CENTER, BOTH, BOTTOM

+    }

+}

diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
index 627ee3c..5a947ef 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
@@ -31,14 +31,14 @@
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
 
-
-/**
- * A row within an {@link XWPFTable}. Rows mostly just have
- *  sizings and stylings, the interesting content lives inside
- *  the child {@link XWPFTableCell}s
- */
-public class XWPFTableRow {
-    private CTRow ctRow;
+

+/**

+ * A row within an {@link XWPFTable}. Rows mostly just have

+ * sizings and stylings, the interesting content lives inside

+ * the child {@link XWPFTableCell}s

+ */

+public class XWPFTableRow {

+    private CTRow ctRow;

     private XWPFTable table;
     private List<XWPFTableCell> tableCells;
 
@@ -52,187 +52,195 @@
     public CTRow getCtRow() {
         return ctRow;
     }
-
-    /**
-     * create a new XWPFTableCell and add it to the tableCell-list of this tableRow
-     * @return the newly created XWPFTableCell
-     */
-    public XWPFTableCell createCell() {
-	XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody());
-	tableCells.add(tableCell);
-	return tableCell;
-    }
-
-    public XWPFTableCell getCell(int pos) {
-	if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {
-	    return getTableCells().get(pos);
-	}
-	return null;
-    }
-
-    public void removeCell(int pos) {
-	if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {
-	    tableCells.remove(pos);
-	}    	
-    }
-    /**
-     * adds a new TableCell at the end of this tableRow
-     */
-    public XWPFTableCell addNewTableCell(){
-	CTTc cell = ctRow.addNewTc();
-	XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody());
-	tableCells.add(tableCell);
-	return tableCell;
-    }
-
-    /**
+

+    /**

+     * create a new XWPFTableCell and add it to the tableCell-list of this tableRow

+     *

+     * @return the newly created XWPFTableCell

+     */

+    public XWPFTableCell createCell() {

+        XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody());

+        tableCells.add(tableCell);

+        return tableCell;

+    }

+

+    public XWPFTableCell getCell(int pos) {

+        if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {

+            return getTableCells().get(pos);

+        }

+        return null;

+    }

+

+    public void removeCell(int pos) {

+        if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {

+            tableCells.remove(pos);

+        }

+    }

+

+    /**

+     * adds a new TableCell at the end of this tableRow

+     */

+    public XWPFTableCell addNewTableCell() {

+        CTTc cell = ctRow.addNewTc();

+        XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody());

+        tableCells.add(tableCell);

+        return tableCell;

+    }

+

+    /**

      * This element specifies the height of the current table row within the
      * current table. This height shall be used to determine the resulting
      * height of the table row, which may be absolute or relative (depending on
      * its attribute values). If omitted, then the table row shall automatically
-     * resize its height to the height required by its contents (the equivalent
-     * of an hRule value of auto).
-     *
-     * @param height
-     */
-    public void setHeight(int height) {
-	CTTrPr properties = getTrPr();
-	CTHeight h = properties.sizeOfTrHeightArray() == 0 ? properties.addNewTrHeight() : properties.getTrHeightArray(0);
-	h.setVal(new BigInteger("" + height));
-    }
-
-    /**
+     * resize its height to the height required by its contents (the equivalent

+     * of an hRule value of auto).

+     *

+     * @return height

+     */

+    public int getHeight() {

+        CTTrPr properties = getTrPr();

+        return properties.sizeOfTrHeightArray() == 0 ? 0 : properties.getTrHeightArray(0).getVal().intValue();

+    }

+

+    /**

      * This element specifies the height of the current table row within the
      * current table. This height shall be used to determine the resulting
      * height of the table row, which may be absolute or relative (depending on
      * its attribute values). If omitted, then the table row shall automatically
-     * resize its height to the height required by its contents (the equivalent
-     * of an hRule value of auto).
-     *
-     * @return height
-     */
-    public int getHeight() {
-	CTTrPr properties = getTrPr();
-	return properties.sizeOfTrHeightArray() == 0 ? 0 : properties.getTrHeightArray(0).getVal().intValue();
-    }
-
-    private CTTrPr getTrPr() {
-	return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr();
-    }
-
-    public XWPFTable getTable(){
-	return table;
-    }
-
-    /**
-     * create and return a list of all XWPFTableCell
-     * who belongs to this row
-     * @return a list of {@link XWPFTableCell} 
-     */
-    public List<ICell> getTableICells(){
-    
-        List<ICell> cells = new ArrayList<ICell>();
-        //Can't use ctRow.getTcList because that only gets table cells
-        //Can't use ctRow.getSdtList because that only gets sdts that are at cell level
+     * resize its height to the height required by its contents (the equivalent

+     * of an hRule value of auto).

+     *

+     * @param height

+     */

+    public void setHeight(int height) {

+        CTTrPr properties = getTrPr();

+        CTHeight h = properties.sizeOfTrHeightArray() == 0 ? properties.addNewTrHeight() : properties.getTrHeightArray(0);

+        h.setVal(new BigInteger("" + height));

+    }

+

+    private CTTrPr getTrPr() {

+        return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr();

+    }

+

+    public XWPFTable getTable() {

+        return table;

+    }

+

+    /**

+     * create and return a list of all XWPFTableCell

+     * who belongs to this row

+     *

+     * @return a list of {@link XWPFTableCell}

+     */

+    public List<ICell> getTableICells() {

+

+        List<ICell> cells = new ArrayList<ICell>();

+        //Can't use ctRow.getTcList because that only gets table cells

+        //Can't use ctRow.getSdtList because that only gets sdts that are at cell level

         XmlCursor cursor = ctRow.newCursor();
-        cursor.selectPath("./*");
-        while (cursor.toNextSelection()) {
-            XmlObject o = cursor.getObject();
-            if (o instanceof CTTc){
-                cells.add(new XWPFTableCell((CTTc)o, this, table.getBody()));
-            } else if (o instanceof CTSdtCell) {
-                cells.add(new XWPFSDTCell((CTSdtCell)o, this, table.getBody()));
-            }
-        }
-        return cells;
+        cursor.selectPath("./*");

+        while (cursor.toNextSelection()) {

+            XmlObject o = cursor.getObject();

+            if (o instanceof CTTc) {

+                cells.add(new XWPFTableCell((CTTc) o, this, table.getBody()));

+            } else if (o instanceof CTSdtCell) {

+                cells.add(new XWPFSDTCell((CTSdtCell) o, this, table.getBody()));

+            }

+        }

+        return cells;

     }
 
-    /**
-     * create and return a list of all XWPFTableCell
-     * who belongs to this row
-     * @return a list of {@link XWPFTableCell} 
-     */
-    @SuppressWarnings("deprecation")
-    public List<XWPFTableCell> getTableCells(){
-	if(tableCells == null){
-	    List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
-	    for (CTTc tableCell : ctRow.getTcArray()) {
-		cells.add(new XWPFTableCell(tableCell, this, table.getBody()));
-	    }
-       //TODO: it is possible to have an SDT that contains a cell in within a row
-       //need to modify this code so that it pulls out SDT wrappers around cells, too.
-
-	    this.tableCells = cells;
-	}
-	return tableCells;
-    }
-
-    /**
+    /**

+     * create and return a list of all XWPFTableCell

+     * who belongs to this row

+     *

+     * @return a list of {@link XWPFTableCell}

+     */

+    @SuppressWarnings("deprecation")

+    public List<XWPFTableCell> getTableCells() {

+        if (tableCells == null) {

+            List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();

+            for (CTTc tableCell : ctRow.getTcArray()) {

+                cells.add(new XWPFTableCell(tableCell, this, table.getBody()));

+            }

+            //TODO: it is possible to have an SDT that contains a cell in within a row

+            //need to modify this code so that it pulls out SDT wrappers around cells, too.

+

+            this.tableCells = cells;

+        }

+        return tableCells;

+    }

+

+    /**

      * returns the XWPFTableCell which belongs to the CTTC cell
-     * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned
-     */
-    public XWPFTableCell getTableCell(CTTc cell) {
-	for(int i=0; i<tableCells.size(); i++){
-	    if (tableCells.get(i).getCTTc() == cell)
-		return tableCells.get(i); 
-	}
-	return null;
-    }
-
-    /**
-     * This attribute controls whether to allow table rows to split across pages.
-     * The logic for this attribute is a little unusual: a true value means
-     * DON'T allow rows to split, false means allow rows to split.
-     * @param split - if true, don't allow rows to be split. If false, allow
-     *        rows to be split.
-     */
-    public void setCantSplitRow(boolean split) {
-	CTTrPr trpr = getTrPr();
-	CTOnOff onoff = trpr.addNewCantSplit();
-	onoff.setVal(split ? STOnOff.ON : STOnOff.OFF);
-    }
-
-    /**
-     * Return true if the "can't split row" value is true. The logic for this
-     * attribute is a little unusual: a TRUE value means DON'T allow rows to
-     * split, FALSE means allow rows to split.
-     * @return true if rows can't be split, false otherwise.
-     */
-    public boolean isCantSplitRow() {
-	boolean isCant = false;
-	CTTrPr trpr = getTrPr();
-	if (trpr.sizeOfCantSplitArray() > 0) {
-	    CTOnOff onoff = trpr.getCantSplitArray(0);
-	    isCant = onoff.getVal().equals(STOnOff.ON);
-	}
-	return isCant;
-    }
-
-    /**
-     * This attribute controls whether to repeat a table's header row at the top
-     * of a table split across pages.
-     * @param repeat - if TRUE, repeat header row at the top of each page of table;
-     *                 if FALSE, don't repeat header row.
-     */
-    public void setRepeatHeader(boolean repeat) {
-	CTTrPr trpr = getTrPr();
-	CTOnOff onoff = trpr.addNewTblHeader();
-	onoff.setVal(repeat ? STOnOff.ON : STOnOff.OFF);
-    }
-
-    /**
-     * Return true if a table's header row should be repeated at the top of a
-     * table split across pages.
-     * @return true if table's header row should be repeated at the top of each
-     *         page of table, false otherwise.
-     */
-    public boolean isRepeatHeader() {
-	boolean repeat = false;
-	CTTrPr trpr = getTrPr();
-	if (trpr.sizeOfTblHeaderArray() > 0) {
-	    CTOnOff rpt = trpr.getTblHeaderArray(0);
-	    repeat = rpt.getVal().equals(STOnOff.ON);
-	}
-	return repeat;
-    }
-}
+     * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned

+     */

+    public XWPFTableCell getTableCell(CTTc cell) {

+        for (int i = 0; i < tableCells.size(); i++) {

+            if (tableCells.get(i).getCTTc() == cell)

+                return tableCells.get(i);

+        }

+        return null;

+    }

+

+    /**

+     * Return true if the "can't split row" value is true. The logic for this

+     * attribute is a little unusual: a TRUE value means DON'T allow rows to

+     * split, FALSE means allow rows to split.

+     *

+     * @return true if rows can't be split, false otherwise.

+     */

+    public boolean isCantSplitRow() {

+        boolean isCant = false;

+        CTTrPr trpr = getTrPr();

+        if (trpr.sizeOfCantSplitArray() > 0) {

+            CTOnOff onoff = trpr.getCantSplitArray(0);

+            isCant = onoff.getVal().equals(STOnOff.ON);

+        }

+        return isCant;

+    }

+

+    /**

+     * This attribute controls whether to allow table rows to split across pages.

+     * The logic for this attribute is a little unusual: a true value means

+     * DON'T allow rows to split, false means allow rows to split.

+     *

+     * @param split - if true, don't allow rows to be split. If false, allow

+     *              rows to be split.

+     */

+    public void setCantSplitRow(boolean split) {

+        CTTrPr trpr = getTrPr();

+        CTOnOff onoff = trpr.addNewCantSplit();

+        onoff.setVal(split ? STOnOff.ON : STOnOff.OFF);

+    }

+

+    /**

+     * Return true if a table's header row should be repeated at the top of a

+     * table split across pages.

+     *

+     * @return true if table's header row should be repeated at the top of each

+     * page of table, false otherwise.

+     */

+    public boolean isRepeatHeader() {

+        boolean repeat = false;

+        CTTrPr trpr = getTrPr();

+        if (trpr.sizeOfTblHeaderArray() > 0) {

+            CTOnOff rpt = trpr.getTblHeaderArray(0);

+            repeat = rpt.getVal().equals(STOnOff.ON);

+        }

+        return repeat;

+    }

+

+    /**

+     * This attribute controls whether to repeat a table's header row at the top

+     * of a table split across pages.

+     *

+     * @param repeat - if TRUE, repeat header row at the top of each page of table;

+     *               if FALSE, don't repeat header row.

+     */

+    public void setRepeatHeader(boolean repeat) {

+        CTTrPr trpr = getTrPr();

+        CTOnOff onoff = trpr.addNewTblHeader();

+        onoff.setVal(repeat ? STOnOff.ON : STOnOff.OFF);

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
index f4e39ab..55f4093 100644
--- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
+++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
@@ -155,13 +155,16 @@
     public void testRelationOrder() throws Exception {
         OPCPackage pkg = PackageHelper.open(POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx"));
         OPCParser doc = new OPCParser(pkg);
-        doc.parse(new TestFactory());
-
-        for(POIXMLDocumentPart rel : doc.getRelations()){
-            //TODO finish me
-            assertNotNull(rel);
+        try {
+            doc.parse(new TestFactory());
+    
+            for(POIXMLDocumentPart rel : doc.getRelations()){
+                //TODO finish me
+                assertNotNull(rel);
+            }
+        } finally {
+        	doc.close();
         }
-
     }
 
     public void testCommitNullPart() throws IOException, InvalidFormatException {
diff --git a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java
index 7f79afa..a8644f4 100644
--- a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java
+++ b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java
@@ -25,6 +25,7 @@
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.POIOLE2TextExtractor;
 import org.apache.poi.POITextExtractor;
+import org.apache.poi.POIXMLException;
 import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.hdgf.extractor.VisioTextExtractor;
 import org.apache.poi.hpbf.extractor.PublisherTextExtractor;
@@ -47,252 +48,290 @@
  * Test that the extractor factory plays nicely
  */
 public class TestExtractorFactory extends TestCase {
+    private File txt;
 
-   private File txt;
+    private File xls;
+    private File xlsx;
+    private File xlsxStrict;
+    private File xltx;
+    private File xlsEmb;
 
-   private File xls;
-   private File xlsx;
-   private File xltx;
-   private File xlsEmb;
+    private File doc;
+    private File doc6;
+    private File doc95;
+    private File docx;
+    private File dotx;
+    private File docEmb;
+    private File docEmbOOXML;
 
-   private File doc;
-   private File doc6;
-   private File doc95;
-   private File docx;
-   private File dotx;
-   private File docEmb;
-   private File docEmbOOXML;
+    private File ppt;
+    private File pptx;
 
-   private File ppt;
-   private File pptx;
+    private File msg;
+    private File msgEmb;
+    private File msgEmbMsg;
 
-   private File msg;
-   private File msgEmb;
-   private File msgEmbMsg;
-   
-   private File vsd;
-   
-   private File pub;
+    private File vsd;
+    private File vsdx;
 
-   private File getFileAndCheck(POIDataSamples samples, String name) {
-       File file = samples.getFile(name);
-       
-       assertNotNull("Did not get a file for " + name, file);
-       assertTrue("Did not get a type file for " + name, file.isFile());
-       assertTrue("File did not exist: " + name, file.exists());
-       
-       return file;
-   }
-   @Override
-   protected void setUp() throws Exception {
-      super.setUp();
+    private File pub;
 
-      POIDataSamples ssTests = POIDataSamples.getSpreadSheetInstance();
-      xls = getFileAndCheck(ssTests, "SampleSS.xls");
-      xlsx = getFileAndCheck(ssTests, "SampleSS.xlsx");
-      xltx = getFileAndCheck(ssTests, "test.xltx");
-      xlsEmb = getFileAndCheck(ssTests, "excel_with_embeded.xls");
+    private File getFileAndCheck(POIDataSamples samples, String name) {
+        File file = samples.getFile(name);
 
-      POIDataSamples wpTests = POIDataSamples.getDocumentInstance();
-      doc = getFileAndCheck(wpTests, "SampleDoc.doc");
-      doc6 = getFileAndCheck(wpTests, "Word6.doc");
-      doc95 = getFileAndCheck(wpTests, "Word95.doc");
-      docx = getFileAndCheck(wpTests, "SampleDoc.docx");
-      dotx = getFileAndCheck(wpTests, "test.dotx");
-      docEmb = getFileAndCheck(wpTests, "word_with_embeded.doc");
-      docEmbOOXML = getFileAndCheck(wpTests, "word_with_embeded_ooxml.doc");
+        assertNotNull("Did not get a file for " + name, file);
+        assertTrue("Did not get a type file for " + name, file.isFile());
+        assertTrue("File did not exist: " + name, file.exists());
 
-      POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
-      ppt = getFileAndCheck(slTests, "SampleShow.ppt");
-      pptx = getFileAndCheck(slTests, "SampleShow.pptx");
-      txt = getFileAndCheck(slTests, "SampleShow.txt");
+        return file;
+    }
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
 
-      POIDataSamples dgTests = POIDataSamples.getDiagramInstance();
-      vsd = getFileAndCheck(dgTests, "Test_Visio-Some_Random_Text.vsd");
-      
-      POIDataSamples pubTests = POIDataSamples.getPublisherInstance();
-      pub = getFileAndCheck(pubTests, "Simple.pub");
-      
-      POIDataSamples olTests = POIDataSamples.getHSMFInstance();
-      msg = getFileAndCheck(olTests, "quick.msg");
-      msgEmb = getFileAndCheck(olTests, "attachment_test_msg.msg");
-      msgEmbMsg = getFileAndCheck(olTests, "attachment_msg_pdf.msg");
-   }
+        POIDataSamples ssTests = POIDataSamples.getSpreadSheetInstance();
+        xls = getFileAndCheck(ssTests, "SampleSS.xls");
+        xlsx = getFileAndCheck(ssTests, "SampleSS.xlsx");
+        xlsxStrict = getFileAndCheck(ssTests, "SampleSS.strict.xlsx");
+        xltx = getFileAndCheck(ssTests, "test.xltx");
+        xlsEmb = getFileAndCheck(ssTests, "excel_with_embeded.xls");
 
-   public void testFile() throws Exception {
-      // Excel
-      POITextExtractor xlsExtractor = ExtractorFactory.createExtractor(xls);
-      assertNotNull("Had empty extractor for " + xls, xlsExtractor);
-      assertTrue("Expected instanceof ExcelExtractor, but had: " + xlsExtractor.getClass(), 
-            xlsExtractor
-            instanceof ExcelExtractor
-      );
-      assertTrue(
-            xlsExtractor.getText().length() > 200
-      );
-      xlsExtractor.close();
+        POIDataSamples wpTests = POIDataSamples.getDocumentInstance();
+        doc = getFileAndCheck(wpTests, "SampleDoc.doc");
+        doc6 = getFileAndCheck(wpTests, "Word6.doc");
+        doc95 = getFileAndCheck(wpTests, "Word95.doc");
+        docx = getFileAndCheck(wpTests, "SampleDoc.docx");
+        dotx = getFileAndCheck(wpTests, "test.dotx");
+        docEmb = getFileAndCheck(wpTests, "word_with_embeded.doc");
+        docEmbOOXML = getFileAndCheck(wpTests, "word_with_embeded_ooxml.doc");
 
-      POITextExtractor extractor = ExtractorFactory.createExtractor(xlsx);
-      assertTrue(
-            extractor
-            instanceof XSSFExcelExtractor
-      );
-      extractor.close();
+        POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
+        ppt = getFileAndCheck(slTests, "SampleShow.ppt");
+        pptx = getFileAndCheck(slTests, "SampleShow.pptx");
+        txt = getFileAndCheck(slTests, "SampleShow.txt");
 
-      extractor = ExtractorFactory.createExtractor(xlsx);
-      assertTrue(
-            extractor.getText().length() > 200
-      );
-      extractor.close();
+        POIDataSamples dgTests = POIDataSamples.getDiagramInstance();
+        vsd = getFileAndCheck(dgTests, "Test_Visio-Some_Random_Text.vsd");
+        vsdx = getFileAndCheck(dgTests, "test.vsdx");
 
-      extractor = ExtractorFactory.createExtractor(xltx);
-      assertTrue(
-            extractor
-            instanceof XSSFExcelExtractor
-      );
-      extractor.close();
+        POIDataSamples pubTests = POIDataSamples.getPublisherInstance();
+        pub = getFileAndCheck(pubTests, "Simple.pub");
 
-      extractor = ExtractorFactory.createExtractor(xltx);
-      assertTrue(
-            extractor.getText().contains("test")
-      );
-      extractor.close();
+        POIDataSamples olTests = POIDataSamples.getHSMFInstance();
+        msg = getFileAndCheck(olTests, "quick.msg");
+        msgEmb = getFileAndCheck(olTests, "attachment_test_msg.msg");
+        msgEmbMsg = getFileAndCheck(olTests, "attachment_msg_pdf.msg");
+    }
+
+    public void testFile() throws Exception {
+        // Excel
+        POITextExtractor xlsExtractor = ExtractorFactory.createExtractor(xls);
+        assertNotNull("Had empty extractor for " + xls, xlsExtractor);
+        assertTrue("Expected instanceof ExcelExtractor, but had: " + xlsExtractor.getClass(), 
+                xlsExtractor
+                instanceof ExcelExtractor
+        );
+        assertTrue(
+                xlsExtractor.getText().length() > 200
+        );
+        xlsExtractor.close();
+
+        POITextExtractor extractor = ExtractorFactory.createExtractor(xlsx);
+        assertTrue(
+                extractor
+                instanceof XSSFExcelExtractor
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(xlsx);
+        assertTrue(
+                extractor.getText().length() > 200
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(xltx);
+        assertTrue(
+                extractor
+                instanceof XSSFExcelExtractor
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(xltx);
+        assertTrue(
+                extractor.getText().contains("test")
+        );
+        extractor.close();
+
+        // TODO Support OOXML-Strict, see bug #57699
+        try {
+            extractor = ExtractorFactory.createExtractor(xlsxStrict);
+            fail("OOXML-Strict isn't yet supported");
+        } catch (POIXMLException e) {
+            // Expected, for now
+        }
+//        extractor = ExtractorFactory.createExtractor(xlsxStrict);
+//        assertTrue(
+//                extractor
+//                instanceof XSSFExcelExtractor
+//        );
+//        extractor.close();
+//
+//        extractor = ExtractorFactory.createExtractor(xlsxStrict);
+//        assertTrue(
+//                extractor.getText().contains("test")
+//        );
+//        extractor.close();
 
 
-      // Word
-      assertTrue(
-            ExtractorFactory.createExtractor(doc)
-            instanceof WordExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(doc).getText().length() > 120
-      );
+        // Word
+        assertTrue(
+                ExtractorFactory.createExtractor(doc)
+                instanceof WordExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(doc).getText().length() > 120
+        );
 
-      assertTrue(
-            ExtractorFactory.createExtractor(doc6)
-            instanceof Word6Extractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(doc6).getText().length() > 20
-      );
-      
-      assertTrue(
-            ExtractorFactory.createExtractor(doc95)
-            instanceof Word6Extractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(doc95).getText().length() > 120
-      );
-          
-      extractor = ExtractorFactory.createExtractor(docx);
-      assertTrue(
-            extractor instanceof XWPFWordExtractor
-      );
-      extractor.close();
-      
-      extractor = ExtractorFactory.createExtractor(docx);
-      assertTrue(
-            extractor.getText().length() > 120
-      );
-      extractor.close();
+        assertTrue(
+                ExtractorFactory.createExtractor(doc6)
+                instanceof Word6Extractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(doc6).getText().length() > 20
+        );
 
-      extractor = ExtractorFactory.createExtractor(dotx);
-      assertTrue(
-            extractor instanceof XWPFWordExtractor
-      );
-      extractor.close();
-      
-      extractor = ExtractorFactory.createExtractor(dotx);
-      assertTrue(
-            extractor.getText().contains("Test")
-      );
-      extractor.close();
+        assertTrue(
+                ExtractorFactory.createExtractor(doc95)
+                instanceof Word6Extractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(doc95).getText().length() > 120
+        );
 
-      // PowerPoint
-      assertTrue(
-            ExtractorFactory.createExtractor(ppt)
-            instanceof PowerPointExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(ppt).getText().length() > 120
-      );
+        extractor = ExtractorFactory.createExtractor(docx);
+        assertTrue(
+                extractor instanceof XWPFWordExtractor
+        );
+        extractor.close();
 
-      extractor = ExtractorFactory.createExtractor(pptx);
-      assertTrue(
-            extractor
-            instanceof XSLFPowerPointExtractor
-      );
-      extractor.close();
+        extractor = ExtractorFactory.createExtractor(docx);
+        assertTrue(
+                extractor.getText().length() > 120
+        );
+        extractor.close();
 
-      extractor = ExtractorFactory.createExtractor(pptx);
-      assertTrue(
-            extractor.getText().length() > 120
-      );
-      extractor.close();
+        extractor = ExtractorFactory.createExtractor(dotx);
+        assertTrue(
+                extractor instanceof XWPFWordExtractor
+        );
+        extractor.close();
 
-      // Visio
-      assertTrue(
-            ExtractorFactory.createExtractor(vsd)
-            instanceof VisioTextExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(vsd).getText().length() > 50
-      );
-      
-      // Publisher
-      assertTrue(
-            ExtractorFactory.createExtractor(pub)
-            instanceof PublisherTextExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(pub).getText().length() > 50
-      );
-      
-      // Outlook msg
-      assertTrue(
-            ExtractorFactory.createExtractor(msg)
-            instanceof OutlookTextExtactor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(msg).getText().length() > 50
-      );
+        extractor = ExtractorFactory.createExtractor(dotx);
+        assertTrue(
+                extractor.getText().contains("Test")
+        );
+        extractor.close();
 
-      // Text
-      try {
-         ExtractorFactory.createExtractor(txt);
-         fail();
-      } catch(IllegalArgumentException e) {
-         // Good
-      }
-	}
-	
-	public void testInputStream() throws Exception {
-		// Excel
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(xls))
-				instanceof ExcelExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(xls)).getText().length() > 200
-		);
-		
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(xlsx))
-				instanceof XSSFExcelExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(xlsx)).getText().length() > 200
-		);
-		
-		// Word
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(doc))
-				instanceof WordExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(doc)).getText().length() > 120
-		);
-		
+        // PowerPoint
+        assertTrue(
+                ExtractorFactory.createExtractor(ppt)
+                instanceof PowerPointExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(ppt).getText().length() > 120
+        );
+
+        extractor = ExtractorFactory.createExtractor(pptx);
+        assertTrue(
+                extractor
+                instanceof XSLFPowerPointExtractor
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(pptx);
+        assertTrue(
+                extractor.getText().length() > 120
+        );
+        extractor.close();
+
+        // Visio - binary
+        assertTrue(
+                ExtractorFactory.createExtractor(vsd)
+                instanceof VisioTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(vsd).getText().length() > 50
+        );
+        // Visio - vsdx
+        try {
+            ExtractorFactory.createExtractor(vsdx);
+            fail();
+        } catch(IllegalArgumentException e) {
+            // Good
+        }
+
+        // Publisher
+        assertTrue(
+                ExtractorFactory.createExtractor(pub)
+                instanceof PublisherTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(pub).getText().length() > 50
+        );
+
+        // Outlook msg
+        assertTrue(
+                ExtractorFactory.createExtractor(msg)
+                instanceof OutlookTextExtactor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(msg).getText().length() > 50
+        );
+
+        // Text
+        try {
+            ExtractorFactory.createExtractor(txt);
+            fail();
+        } catch(IllegalArgumentException e) {
+            // Good
+        }
+    }
+
+    public void testInputStream() throws Exception {
+        // Excel
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(xls))
+                instanceof ExcelExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(xls)).getText().length() > 200
+        );
+
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(xlsx))
+                instanceof XSSFExcelExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(xlsx)).getText().length() > 200
+        );
+        // TODO Support OOXML-Strict, see bug #57699
+//        assertTrue(
+//                ExtractorFactory.createExtractor(new FileInputStream(xlsxStrict))
+//                instanceof XSSFExcelExtractor
+//        );
+//        assertTrue(
+//                ExtractorFactory.createExtractor(new FileInputStream(xlsxStrict)).getText().length() > 200
+//        );
+
+        // Word
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(doc))
+                instanceof WordExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(doc)).getText().length() > 120
+        );
+
         assertTrue(
                 ExtractorFactory.createExtractor(new FileInputStream(doc6))
                 instanceof Word6Extractor
@@ -300,7 +339,7 @@
         assertTrue(
                 ExtractorFactory.createExtractor(new FileInputStream(doc6)).getText().length() > 20
         );
-        
+
         assertTrue(
                 ExtractorFactory.createExtractor(new FileInputStream(doc95))
                 instanceof Word6Extractor
@@ -308,92 +347,99 @@
         assertTrue(
                 ExtractorFactory.createExtractor(new FileInputStream(doc95)).getText().length() > 120
         );
-        
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(docx))
-				instanceof XWPFWordExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(docx)).getText().length() > 120
-		);
-		
-		// PowerPoint
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(ppt))
-				instanceof PowerPointExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(ppt)).getText().length() > 120
-		);
-		
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(pptx))
-				instanceof XSLFPowerPointExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(pptx)).getText().length() > 120
-		);
-		
-		// Visio
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(vsd))
-				instanceof VisioTextExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new FileInputStream(vsd)).getText().length() > 50
-		);
-		
-      // Publisher
-      assertTrue(
-            ExtractorFactory.createExtractor(new FileInputStream(pub))
-            instanceof PublisherTextExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(new FileInputStream(pub)).getText().length() > 50
-      );
-      
-		// Outlook msg
-      assertTrue(
-            ExtractorFactory.createExtractor(new FileInputStream(msg))
-            instanceof OutlookTextExtactor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(new FileInputStream(msg)).getText().length() > 50
-      );
-		
-		// Text
-		try {
-			FileInputStream stream = new FileInputStream(txt);
-			try {
+
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(docx))
+                instanceof XWPFWordExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(docx)).getText().length() > 120
+        );
+
+        // PowerPoint
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(ppt))
+                instanceof PowerPointExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(ppt)).getText().length() > 120
+        );
+
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(pptx))
+                instanceof XSLFPowerPointExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(pptx)).getText().length() > 120
+        );
+
+        // Visio
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(vsd))
+                instanceof VisioTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(vsd)).getText().length() > 50
+        );
+        // Visio - vsdx
+        try {
+            ExtractorFactory.createExtractor(new FileInputStream(vsdx));
+            fail();
+        } catch(IllegalArgumentException e) {
+            // Good
+        }
+
+        // Publisher
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(pub))
+                instanceof PublisherTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(pub)).getText().length() > 50
+        );
+
+        // Outlook msg
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(msg))
+                instanceof OutlookTextExtactor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new FileInputStream(msg)).getText().length() > 50
+        );
+
+        // Text
+        try {
+            FileInputStream stream = new FileInputStream(txt);
+            try {
                 ExtractorFactory.createExtractor(stream);
-    			fail();
-			} finally {
-			    stream.close();
-			}
-		} catch(IllegalArgumentException e) {
-			// Good
-		}
-	}
-	
-	public void testPOIFS() throws Exception {
-		// Excel
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)))
-				instanceof ExcelExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))).getText().length() > 200
-		);
-		
-		// Word
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc)))
-				instanceof WordExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc))).getText().length() > 120
-		);
-		
+                fail();
+            } finally {
+                stream.close();
+            }
+        } catch(IllegalArgumentException e) {
+            // Good
+        }
+    }
+
+    public void testPOIFS() throws Exception {
+        // Excel
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)))
+                instanceof ExcelExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls))).getText().length() > 200
+        );
+
+        // Word
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc)))
+                instanceof WordExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc))).getText().length() > 120
+        );
+
         assertTrue(
                 ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc6)))
                 instanceof Word6Extractor
@@ -401,7 +447,7 @@
         assertTrue(
                 ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc6))).getText().length() > 20
         );
-        
+
         assertTrue(
                 ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc95)))
                 instanceof Word6Extractor
@@ -409,297 +455,297 @@
         assertTrue(
                 ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(doc95))).getText().length() > 120
         );
-        
-		// PowerPoint
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt)))
-				instanceof PowerPointExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt))).getText().length() > 120
-		);
-		
-		// Visio
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd)))
-				instanceof VisioTextExtractor
-		);
-		assertTrue(
-				ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd))).getText().length() > 50
-		);
-      
-      // Publisher
-      assertTrue(
-            ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub)))
-            instanceof PublisherTextExtractor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub))).getText().length() > 50
-      );
-		
-      // Outlook msg
-      assertTrue(
-            ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg)))
-            instanceof OutlookTextExtactor
-      );
-      assertTrue(
-            ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg))).getText().length() > 50
-      );
-      
-		// Text
-		try {
-			ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(txt)));
-			fail();
-		} catch(IOException e) {
-			// Good
-		}
-	}
-	
-	public void testPackage() throws Exception {
-		// Excel
-		POIXMLTextExtractor extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
+
+        // PowerPoint
         assertTrue(
-				extractor
-				instanceof XSSFExcelExtractor
-		);
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt)))
+                instanceof PowerPointExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(ppt))).getText().length() > 120
+        );
+
+        // Visio
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd)))
+                instanceof VisioTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(vsd))).getText().length() > 50
+        );
+
+        // Publisher
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub)))
+                instanceof PublisherTextExtractor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(pub))).getText().length() > 50
+        );
+
+        // Outlook msg
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg)))
+                instanceof OutlookTextExtactor
+        );
+        assertTrue(
+                ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(msg))).getText().length() > 50
+        );
+
+        // Text
+        try {
+            ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(txt)));
+            fail();
+        } catch(IOException e) {
+            // Good
+        }
+    }
+
+    public void testPackage() throws Exception {
+        // Excel
+        POIXMLTextExtractor extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
+        assertTrue(
+                extractor
+                instanceof XSSFExcelExtractor
+        );
         extractor.close();
-		extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString()));
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString()));
         assertTrue(extractor.getText().length() > 200);
         extractor.close();
-		
-		// Word
-		extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString()));
+
+        // Word
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString()));
         assertTrue(
-				extractor
-				instanceof XWPFWordExtractor
-		);
-        extractor.close();
-        
-		extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString()));
-        assertTrue(
-				extractor.getText().length() > 120
-		);
-        extractor.close();
-		
-		// PowerPoint
-		extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString()));
-        assertTrue(
-				extractor
-				instanceof XSLFPowerPointExtractor
-		);
+                extractor
+                instanceof XWPFWordExtractor
+        );
         extractor.close();
 
-		extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString()));
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(docx.toString()));
         assertTrue(
-				extractor.getText().length() > 120
-		);
+                extractor.getText().length() > 120
+        );
         extractor.close();
-		
-		// Text
-		try {
-			ExtractorFactory.createExtractor(OPCPackage.open(txt.toString()));
-			fail();
-		} catch(InvalidOperationException e) {
-			// Good
-		}
-	}
-	
-	public void testPreferEventBased() throws Exception {
-	   assertFalse(ExtractorFactory.getPreferEventExtractor());
-	   assertFalse(ExtractorFactory.getThreadPrefersEventExtractors());
-	   assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
-	   
-	   ExtractorFactory.setThreadPrefersEventExtractors(true);
-	   
-      assertTrue(ExtractorFactory.getPreferEventExtractor());
-      assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
-      assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
-      
-      ExtractorFactory.setAllThreadsPreferEventExtractors(false);
-      
-      assertFalse(ExtractorFactory.getPreferEventExtractor());
-      assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
-      assertEquals(Boolean.FALSE, ExtractorFactory.getAllThreadsPreferEventExtractors());
-      
-      ExtractorFactory.setAllThreadsPreferEventExtractors(null);
-      
-      assertTrue(ExtractorFactory.getPreferEventExtractor());
-      assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
-      assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
-      
-      
-      // Check we get the right extractors now
-      POITextExtractor extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
-      assertTrue(
-            extractor
-            instanceof EventBasedExcelExtractor
-      );
-      extractor.close();
-      extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
-      assertTrue(
-            extractor.getText().length() > 200
-      );
-      extractor.close();
-      
-      extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
-      assertTrue(extractor instanceof XSSFEventBasedExcelExtractor);
-      extractor.close();
 
-      extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
-      assertTrue(
-            extractor.getText().length() > 200
-      );
-      extractor.close();
-      
-      
-      // Put back to normal
-      ExtractorFactory.setThreadPrefersEventExtractors(false);
-      assertFalse(ExtractorFactory.getPreferEventExtractor());
-      assertFalse(ExtractorFactory.getThreadPrefersEventExtractors());
-      assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
-      
-      // And back
-      extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
-      assertTrue(
-            extractor
-            instanceof ExcelExtractor
-      );
-      extractor.close();
-      extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
-      assertTrue(
-            extractor.getText().length() > 200
-      );
-      extractor.close();
-      
-      extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
-      assertTrue(
-            extractor
-            instanceof XSSFExcelExtractor
-      );
-      extractor.close();
-      extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString()));
-      assertTrue(
-            extractor.getText().length() > 200
-      );
-      extractor.close();
-	}
+        // PowerPoint
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString()));
+        assertTrue(
+                extractor
+                instanceof XSLFPowerPointExtractor
+        );
+        extractor.close();
 
-   /**
-    * Test embeded docs text extraction. For now, only
-    *  does poifs embeded, but will do ooxml ones 
-    *  at some point.
-    */
-   public void testEmbeded() throws Exception {
-      POIOLE2TextExtractor ext;
-      POITextExtractor[] embeds;
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString()));
+        assertTrue(
+                extractor.getText().length() > 120
+        );
+        extractor.close();
 
-      // No embedings
-      ext = (POIOLE2TextExtractor)
-      ExtractorFactory.createExtractor(xls);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
-      assertEquals(0, embeds.length);
+        // Text
+        try {
+            ExtractorFactory.createExtractor(OPCPackage.open(txt.toString()));
+            fail();
+        } catch(InvalidOperationException e) {
+            // Good
+        }
+    }
 
-      // Excel
-      ext = (POIOLE2TextExtractor)
-      ExtractorFactory.createExtractor(xlsEmb);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+    public void testPreferEventBased() throws Exception {
+        assertFalse(ExtractorFactory.getPreferEventExtractor());
+        assertFalse(ExtractorFactory.getThreadPrefersEventExtractors());
+        assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
 
-      assertEquals(6, embeds.length);
-      int numWord = 0, numXls = 0, numPpt = 0, numMsg = 0, numWordX;
-      for(int i=0; i<embeds.length; i++) {
-         assertTrue(embeds[i].getText().length() > 20);
+        ExtractorFactory.setThreadPrefersEventExtractors(true);
 
-         if(embeds[i] instanceof PowerPointExtractor) numPpt++;
-         else if(embeds[i] instanceof ExcelExtractor) numXls++;
-         else if(embeds[i] instanceof WordExtractor) numWord++;
-         else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
-      }
-      assertEquals(2, numPpt);
-      assertEquals(2, numXls);
-      assertEquals(2, numWord);
-      assertEquals(0, numMsg);
+        assertTrue(ExtractorFactory.getPreferEventExtractor());
+        assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
+        assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
 
-      // Word
-      ext = (POIOLE2TextExtractor)
-      ExtractorFactory.createExtractor(docEmb);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+        ExtractorFactory.setAllThreadsPreferEventExtractors(false);
 
-      numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
-      assertEquals(4, embeds.length);
-      for(int i=0; i<embeds.length; i++) {
-         assertTrue(embeds[i].getText().length() > 20);
-         if(embeds[i] instanceof PowerPointExtractor) numPpt++;
-         else if(embeds[i] instanceof ExcelExtractor) numXls++;
-         else if(embeds[i] instanceof WordExtractor) numWord++;
-         else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
-      }
-      assertEquals(1, numPpt);
-      assertEquals(2, numXls);
-      assertEquals(1, numWord);
-      assertEquals(0, numMsg);
-      
-      // Word which contains an OOXML file
-      ext = (POIOLE2TextExtractor)
-      ExtractorFactory.createExtractor(docEmbOOXML);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+        assertFalse(ExtractorFactory.getPreferEventExtractor());
+        assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
+        assertEquals(Boolean.FALSE, ExtractorFactory.getAllThreadsPreferEventExtractors());
 
-      numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; numWordX = 0;
-      assertEquals(3, embeds.length);
-      for(int i=0; i<embeds.length; i++) {
-         assertTrue(embeds[i].getText().length() > 20);
-         if(embeds[i] instanceof PowerPointExtractor) numPpt++;
-         else if(embeds[i] instanceof ExcelExtractor) numXls++;
-         else if(embeds[i] instanceof WordExtractor) numWord++;
-         else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
-         else if(embeds[i] instanceof XWPFWordExtractor) numWordX++;
-      }
-      assertEquals(1, numPpt);
-      assertEquals(1, numXls);
-      assertEquals(0, numWord);
-      assertEquals(1, numWordX);
-      assertEquals(0, numMsg);
-      
-      // Outlook
-      ext = (OutlookTextExtactor)
-      ExtractorFactory.createExtractor(msgEmb);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+        ExtractorFactory.setAllThreadsPreferEventExtractors(null);
 
-      numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
-      assertEquals(1, embeds.length);
-      for(int i=0; i<embeds.length; i++) {
-         assertTrue(embeds[i].getText().length() > 20);
-         if(embeds[i] instanceof PowerPointExtractor) numPpt++;
-         else if(embeds[i] instanceof ExcelExtractor) numXls++;
-         else if(embeds[i] instanceof WordExtractor) numWord++;
-         else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
-      }
-      assertEquals(0, numPpt);
-      assertEquals(0, numXls);
-      assertEquals(1, numWord);
-      assertEquals(0, numMsg);
-      
-      // Outlook with another outlook file in it
-      ext = (OutlookTextExtactor)
-      ExtractorFactory.createExtractor(msgEmbMsg);
-      embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+        assertTrue(ExtractorFactory.getPreferEventExtractor());
+        assertTrue(ExtractorFactory.getThreadPrefersEventExtractors());
+        assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
 
-      numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
-      assertEquals(1, embeds.length);
-      for(int i=0; i<embeds.length; i++) {
-         assertTrue(embeds[i].getText().length() > 20);
-         if(embeds[i] instanceof PowerPointExtractor) numPpt++;
-         else if(embeds[i] instanceof ExcelExtractor) numXls++;
-         else if(embeds[i] instanceof WordExtractor) numWord++;
-         else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
-      }
-      assertEquals(0, numPpt);
-      assertEquals(0, numXls);
-      assertEquals(0, numWord);
-      assertEquals(1, numMsg);
-      
 
-      // TODO - PowerPoint
-      // TODO - Publisher
-      // TODO - Visio
-   }
+        // Check we get the right extractors now
+        POITextExtractor extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
+        assertTrue(
+                extractor
+                instanceof EventBasedExcelExtractor
+        );
+        extractor.close();
+        extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
+        assertTrue(
+                extractor.getText().length() > 200
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
+        assertTrue(extractor instanceof XSSFEventBasedExcelExtractor);
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
+        assertTrue(
+                extractor.getText().length() > 200
+        );
+        extractor.close();
+
+
+        // Put back to normal
+        ExtractorFactory.setThreadPrefersEventExtractors(false);
+        assertFalse(ExtractorFactory.getPreferEventExtractor());
+        assertFalse(ExtractorFactory.getThreadPrefersEventExtractors());
+        assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
+
+        // And back
+        extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
+        assertTrue(
+                extractor
+                instanceof ExcelExtractor
+        );
+        extractor.close();
+        extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)));
+        assertTrue(
+                extractor.getText().length() > 200
+        );
+        extractor.close();
+
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString(), PackageAccess.READ));
+        assertTrue(
+                extractor
+                instanceof XSSFExcelExtractor
+        );
+        extractor.close();
+        extractor = ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString()));
+        assertTrue(
+                extractor.getText().length() > 200
+        );
+        extractor.close();
+    }
+
+    /**
+     * Test embeded docs text extraction. For now, only
+     *  does poifs embeded, but will do ooxml ones 
+     *  at some point.
+     */
+    public void testEmbeded() throws Exception {
+        POIOLE2TextExtractor ext;
+        POITextExtractor[] embeds;
+
+        // No embedings
+        ext = (POIOLE2TextExtractor)
+                ExtractorFactory.createExtractor(xls);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+        assertEquals(0, embeds.length);
+
+        // Excel
+        ext = (POIOLE2TextExtractor)
+                ExtractorFactory.createExtractor(xlsEmb);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+
+        assertEquals(6, embeds.length);
+        int numWord = 0, numXls = 0, numPpt = 0, numMsg = 0, numWordX;
+        for(int i=0; i<embeds.length; i++) {
+            assertTrue(embeds[i].getText().length() > 20);
+
+            if(embeds[i] instanceof PowerPointExtractor) numPpt++;
+            else if(embeds[i] instanceof ExcelExtractor) numXls++;
+            else if(embeds[i] instanceof WordExtractor) numWord++;
+            else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
+        }
+        assertEquals(2, numPpt);
+        assertEquals(2, numXls);
+        assertEquals(2, numWord);
+        assertEquals(0, numMsg);
+
+        // Word
+        ext = (POIOLE2TextExtractor)
+                ExtractorFactory.createExtractor(docEmb);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+
+        numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
+        assertEquals(4, embeds.length);
+        for(int i=0; i<embeds.length; i++) {
+            assertTrue(embeds[i].getText().length() > 20);
+            if(embeds[i] instanceof PowerPointExtractor) numPpt++;
+            else if(embeds[i] instanceof ExcelExtractor) numXls++;
+            else if(embeds[i] instanceof WordExtractor) numWord++;
+            else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
+        }
+        assertEquals(1, numPpt);
+        assertEquals(2, numXls);
+        assertEquals(1, numWord);
+        assertEquals(0, numMsg);
+
+        // Word which contains an OOXML file
+        ext = (POIOLE2TextExtractor)
+                ExtractorFactory.createExtractor(docEmbOOXML);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+
+        numWord = 0; numXls = 0; numPpt = 0; numMsg = 0; numWordX = 0;
+        assertEquals(3, embeds.length);
+        for(int i=0; i<embeds.length; i++) {
+            assertTrue(embeds[i].getText().length() > 20);
+            if(embeds[i] instanceof PowerPointExtractor) numPpt++;
+            else if(embeds[i] instanceof ExcelExtractor) numXls++;
+            else if(embeds[i] instanceof WordExtractor) numWord++;
+            else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
+            else if(embeds[i] instanceof XWPFWordExtractor) numWordX++;
+        }
+        assertEquals(1, numPpt);
+        assertEquals(1, numXls);
+        assertEquals(0, numWord);
+        assertEquals(1, numWordX);
+        assertEquals(0, numMsg);
+
+        // Outlook
+        ext = (OutlookTextExtactor)
+                ExtractorFactory.createExtractor(msgEmb);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+
+        numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
+        assertEquals(1, embeds.length);
+        for(int i=0; i<embeds.length; i++) {
+            assertTrue(embeds[i].getText().length() > 20);
+            if(embeds[i] instanceof PowerPointExtractor) numPpt++;
+            else if(embeds[i] instanceof ExcelExtractor) numXls++;
+            else if(embeds[i] instanceof WordExtractor) numWord++;
+            else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
+        }
+        assertEquals(0, numPpt);
+        assertEquals(0, numXls);
+        assertEquals(1, numWord);
+        assertEquals(0, numMsg);
+
+        // Outlook with another outlook file in it
+        ext = (OutlookTextExtactor)
+                ExtractorFactory.createExtractor(msgEmbMsg);
+        embeds = ExtractorFactory.getEmbededDocsTextExtractors(ext);
+
+        numWord = 0; numXls = 0; numPpt = 0; numMsg = 0;
+        assertEquals(1, embeds.length);
+        for(int i=0; i<embeds.length; i++) {
+            assertTrue(embeds[i].getText().length() > 20);
+            if(embeds[i] instanceof PowerPointExtractor) numPpt++;
+            else if(embeds[i] instanceof ExcelExtractor) numXls++;
+            else if(embeds[i] instanceof WordExtractor) numWord++;
+            else if(embeds[i] instanceof OutlookTextExtactor) numMsg++;
+        }
+        assertEquals(0, numPpt);
+        assertEquals(0, numXls);
+        assertEquals(0, numWord);
+        assertEquals(1, numMsg);
+
+
+        // TODO - PowerPoint
+        // TODO - Publisher
+        // TODO - Visio
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java
index 1dcf93a..a1a3ccc 100644
--- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java
+++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllOpenXML4JTests.java
@@ -17,28 +17,24 @@
 
 package org.apache.poi.openxml4j.opc;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import org.apache.poi.openxml4j.opc.compliance.AllOpenXML4JComplianceTests;
 import org.apache.poi.openxml4j.opc.internal.AllOpenXML4JInternalTests;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
 
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+      TestContentType.class
+    , TestFileHelper.class
+    , TestListParts.class
+    , TestPackage.class
+    , TestPackageCoreProperties.class
+    , TestPackagePartName.class
+    , TestPackageThumbnail.class
+    , TestPackagingURIHelper.class
+    , TestRelationships.class
+    , AllOpenXML4JComplianceTests.class
+    , AllOpenXML4JInternalTests.class
+})
 public final class AllOpenXML4JTests {
-
-	public static Test suite() {
-
-		TestSuite suite = new TestSuite(AllOpenXML4JTests.class.getName());
-		suite.addTestSuite(TestContentType.class);
-		suite.addTestSuite(TestFileHelper.class);
-		suite.addTestSuite(TestListParts.class);
-		suite.addTestSuite(TestPackage.class);
-		suite.addTestSuite(TestPackageCoreProperties.class);
-		suite.addTestSuite(TestPackagePartName.class);
-		suite.addTestSuite(TestPackageThumbnail.class);
-		suite.addTestSuite(TestPackagingURIHelper.class);
-		suite.addTestSuite(TestRelationships.class);
-		suite.addTest(AllOpenXML4JComplianceTests.suite());
-		suite.addTest(AllOpenXML4JInternalTests.suite());
-		return suite;
-	}
 }
diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
index 07a2b33..a695595 100644
--- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
+++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
@@ -17,6 +17,14 @@
 
 package org.apache.poi.openxml4j.opc;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -25,35 +33,47 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.net.URI;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.TreeMap;
 import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
 
-import junit.framework.TestCase;
-
+import org.apache.poi.POIXMLException;
 import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
 import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
 import org.apache.poi.openxml4j.opc.internal.FileHelper;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
+import org.apache.poi.openxml4j.opc.internal.ZipHelper;
+import org.apache.poi.openxml4j.util.ZipSecureFile;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.util.DocumentHelper;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.TempFile;
+import org.junit.Ignore;
+import org.junit.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-public final class TestPackage extends TestCase {
+public final class TestPackage {
     private static final POILogger logger = POILogFactory.getLogger(TestPackage.class);
 
 	/**
 	 * Test that just opening and closing the file doesn't alter the document.
 	 */
-	public void testOpenSave() throws Exception {
+    @Test
+	public void openSave() throws Exception {
 		String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");
 
@@ -75,7 +95,8 @@
 	 * Test that when we create a new Package, we give it
 	 *  the correct default content types
 	 */
-	public void testCreateGetsContentTypes() throws Exception {
+    @Test
+	public void createGetsContentTypes() throws Exception {
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");
 
 		// Zap the target file, in case of an earlier run
@@ -107,7 +128,8 @@
 	/**
 	 * Test package creation.
 	 */
-	public void testCreatePackageAddPart() throws Exception {
+    @Test
+	public void createPackageAddPart() throws Exception {
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");
 
 		File expectedFile = OpenXML4JTestDataSamples.getSampleFile("TestCreatePackageOUTPUT.docx");
@@ -153,7 +175,8 @@
 	 *  document and another part, save and re-load and
 	 *  have everything setup as expected
 	 */
-	public void testCreatePackageWithCoreDocument() throws Exception {
+    @Test
+	public void createPackageWithCoreDocument() throws Exception {
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 		OPCPackage pkg = OPCPackage.create(baos);
 
@@ -247,7 +270,8 @@
     /**
 	 * Test package opening.
 	 */
-	public void testOpenPackage() throws Exception {
+    @Test
+	public void openPackage() throws Exception {
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageTMP.docx");
 
 		File inputFile = OpenXML4JTestDataSamples.getSampleFile("TestOpenPackageINPUT.docx");
@@ -306,7 +330,8 @@
 	 *  OutputStream, in addition to the normal writing
 	 *  to a file
 	 */
-	public void testSaveToOutputStream() throws Exception {
+    @Test
+	public void saveToOutputStream() throws Exception {
 		String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");
 
@@ -334,7 +359,8 @@
 	 *  simple InputStream, in addition to the normal
 	 *  reading from a file
 	 */
-	public void testOpenFromInputStream() throws Exception {
+    @Test
+	public void openFromInputStream() throws Exception {
 		String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
 
 		FileInputStream finp = new FileInputStream(originalFile);
@@ -353,7 +379,9 @@
     /**
      * TODO: fix and enable
      */
-    public void disabled_testRemovePartRecursive() throws Exception {
+    @Test
+    @Ignore
+    public void removePartRecursive() throws Exception {
 		String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
 		File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveOUTPUT.docx");
 		File tempFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveTMP.docx");
@@ -369,7 +397,8 @@
 		assertTrue(targetFile.delete());
 	}
 
-	public void testDeletePart() throws InvalidFormatException {
+    @Test
+	public void deletePart() throws InvalidFormatException {
 		TreeMap<PackagePartName, String> expectedValues;
 		TreeMap<PackagePartName, String> values;
 
@@ -426,7 +455,8 @@
 		p.revert();
 	}
 
-	public void testDeletePartRecursive() throws InvalidFormatException {
+    @Test
+	public void deletePartRecursive() throws InvalidFormatException {
 		TreeMap<PackagePartName, String> expectedValues;
 		TreeMap<PackagePartName, String> values;
 
@@ -468,7 +498,8 @@
 	 * Test that we can open a file by path, and then
 	 *  write changes to it.
 	 */
-	public void testOpenFileThenOverwrite() throws Exception {
+    @Test
+	public void openFileThenOverwrite() throws Exception {
         File tempFile = TempFile.createTempFile("poiTesting","tmp");
         File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx");
         FileHelper.copyFile(origFile, tempFile);
@@ -505,7 +536,8 @@
      * Test that we can open a file by path, save it
      *  to another file, then delete both
      */
-    public void testOpenFileThenSaveDelete() throws Exception {
+    @Test
+    public void openFileThenSaveDelete() throws Exception {
         File tempFile = TempFile.createTempFile("poiTesting","tmp");
         File tempFile2 = TempFile.createTempFile("poiTesting","tmp");
         File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx");
@@ -529,7 +561,8 @@
 		return (ContentTypeManager)f.get(pkg);
 	}
 
-    public void testGetPartsByName() throws Exception {
+    @Test
+    public void getPartsByName() throws Exception {
         String filepath =  OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
 
         OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ_WRITE);
@@ -553,7 +586,8 @@
         }
     }
     
-    public void testGetPartSize() throws Exception {
+    @Test
+    public void getPartSize() throws Exception {
        String filepath =  OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
        OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ);
        try {
@@ -585,7 +619,8 @@
        }
     }
 
-    public void testReplaceContentType() throws Exception {
+    @Test
+    public void replaceContentType() throws Exception {
         InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.xlsx");
         OPCPackage p = OPCPackage.open(is);
 
@@ -603,4 +638,131 @@
         assertFalse(mgr.isContentTypeRegister("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"));
         assertTrue(mgr.isContentTypeRegister("application/vnd.ms-excel.sheet.macroEnabled.main+xml"));
     }
+
+    @Test(expected=IOException.class)
+    public void zipBombCreateAndHandle() throws Exception {
+        // #50090 / #56865
+        ZipFile zipFile = ZipHelper.openZipFile(OpenXML4JTestDataSamples.getSampleFile("sample.xlsx"));
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ZipOutputStream append = new ZipOutputStream(bos);
+        // first, copy contents from existing war
+        Enumeration<? extends ZipEntry> entries = zipFile.entries();
+        while (entries.hasMoreElements()) {
+            ZipEntry e2 = entries.nextElement();
+            ZipEntry e = new ZipEntry(e2.getName());
+            e.setTime(e2.getTime());
+            e.setComment(e2.getComment());
+            e.setSize(e2.getSize());
+            
+            append.putNextEntry(e);
+            if (!e.isDirectory()) {
+                InputStream is = zipFile.getInputStream(e);
+                if (e.getName().equals("[Content_Types].xml")) {
+                    ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
+                    IOUtils.copy(is, bos2);
+                    long size = bos2.size()-"</Types>".length();
+                    append.write(bos2.toByteArray(), 0, (int)size);
+                    byte spam[] = new byte[0x7FFF];
+                    for (int i=0; i<spam.length; i++) spam[i] = ' ';
+                    while (size < 0x7FFF0000) {
+                        append.write(spam);
+                        size += spam.length;
+                    }
+                    append.write("</Types>".getBytes());
+                    size += 8;
+                    e.setSize(size);
+                } else {
+                    IOUtils.copy(is, append);
+                }
+            }
+            append.closeEntry();
+        }
+        
+        append.close();
+        zipFile.close();
+
+        byte buf[] = bos.toByteArray();
+        bos = null;
+        
+        Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(buf));
+        wb.getSheetAt(0);
+        wb.close();
+    }
+    
+    @Test
+    public void zipBombCheckSizes() throws Exception {
+        File file = OpenXML4JTestDataSamples.getSampleFile("sample.xlsx");
+
+        try {
+            double min_ratio = Double.MAX_VALUE;
+            long max_size = 0;
+            ZipFile zf = ZipHelper.openZipFile(file);
+            Enumeration<? extends ZipEntry> entries = zf.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry ze = entries.nextElement();
+                double ratio = (double)ze.getCompressedSize() / (double)ze.getSize();
+                min_ratio = Math.min(min_ratio, ratio);
+                max_size = Math.max(max_size, ze.getSize());
+            }
+            zf.close();
+    
+            // use values close to, but within the limits 
+            ZipSecureFile.setMinInflateRatio(min_ratio-0.002);
+            ZipSecureFile.setMaxEntrySize(max_size+1);
+            Workbook wb = WorkbookFactory.create(file, null, true);
+            wb.close();
+    
+            // check ratio out of bounds
+            ZipSecureFile.setMinInflateRatio(min_ratio+0.002);
+            try {
+                wb = WorkbookFactory.create(file, null, true);
+                wb.close();
+                // this is a bit strange, as there will be different exceptions thrown
+                // depending if this executed via "ant test" or within eclipse
+                // maybe a difference in JDK ...
+            } catch (InvalidFormatException e) {
+                checkForZipBombException(e);
+            } catch (POIXMLException e) {
+                checkForZipBombException(e);
+            }
+    
+            // check max entry size ouf of bounds
+            ZipSecureFile.setMinInflateRatio(min_ratio-0.002);
+            ZipSecureFile.setMaxEntrySize(max_size-1);
+            try {
+                wb = WorkbookFactory.create(file, null, true);
+                wb.close();
+            } catch (InvalidFormatException e) {
+                checkForZipBombException(e);
+            } catch (POIXMLException e) {
+                checkForZipBombException(e);
+            }
+        } finally {
+            // reset otherwise a lot of ooxml tests will fail
+            ZipSecureFile.setMinInflateRatio(0.01d);
+            ZipSecureFile.setMaxEntrySize(0xFFFFFFFFl);            
+        }
+    }
+
+    private void checkForZipBombException(Throwable e) {
+        if(e instanceof InvocationTargetException) {
+            InvocationTargetException t = (InvocationTargetException)e;
+            IOException t2 = (IOException)t.getTargetException();
+            if("Zip bomb detected! Exiting.".equals(t2.getMessage())) {
+                return;
+            }
+        }
+        
+        if ("Zip bomb detected! Exiting.".equals(e.getMessage())) {
+            return;
+        }
+        
+        // recursively check the causes for the message as it can be nested further down in the exception-tree
+        if(e.getCause() != null && e.getCause() != e) {
+            checkForZipBombException(e.getCause());
+            return;
+        }
+
+        throw new IllegalStateException("Expected to catch an Exception because of a detected Zip Bomb, but did not find the related error message in the exception", e);        
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java
index 0cf5200..b9517ba 100644
--- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java
+++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java
@@ -17,6 +17,10 @@
 
 package org.apache.poi.openxml4j.opc.compliance;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -34,6 +38,8 @@
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.TempFile;
 
 /**
  * Test core properties Open Packaging Convention compliance.
@@ -224,4 +230,90 @@
 		String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");
 		assertEquals("The element 'modified' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !", msg);
 	}
+	
+    /**
+     * Document with no core properties - testing at the OPC level,
+     *  saving into a new stream
+     */
+    public void testNoCoreProperties_saveNew() throws Exception {
+        String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx";
+        OPCPackage pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath());
+
+        // Verify it has empty properties
+        assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
+        assertNotNull(pkg.getPackageProperties());
+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+
+        // Save and re-load
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        pkg.save(baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+        pkg = OPCPackage.open(bais);
+
+        // An Empty Properties part has been added in the save/load
+        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
+        assertNotNull(pkg.getPackageProperties());
+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+        
+        
+        // Open a new copy of it
+        pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath());
+        
+        // Save and re-load, without having touched the properties yet
+        baos = new ByteArrayOutputStream();
+        pkg.save(baos);
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        pkg = OPCPackage.open(bais);
+        
+        // Check that this too added empty properties without error
+        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
+        assertNotNull(pkg.getPackageProperties());
+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+    }
+
+    /**
+     * Document with no core properties - testing at the OPC level,
+     *  from a temp-file, saving in-place
+     */
+    public void testNoCoreProperties_saveInPlace() throws Exception {
+        String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx";
+
+        // Copy this into a temp file, so we can play with it
+        File tmp = TempFile.createTempFile("poi-test", ".opc");
+        FileOutputStream out = new FileOutputStream(tmp);
+        IOUtils.copy(
+                POIDataSamples.getOpenXML4JInstance().openResourceAsStream(sampleFileName),
+                out);
+        out.close();
+
+        // Open it from that temp file
+        OPCPackage pkg = OPCPackage.open(tmp);
+
+        // Empty properties
+        assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
+        assertNotNull(pkg.getPackageProperties());
+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+
+        // Save and close
+        pkg.close();
+
+
+        // Re-open and check
+        pkg = OPCPackage.open(tmp);
+
+        // An Empty Properties part has been added in the save/load
+        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
+        assertNotNull(pkg.getPackageProperties());
+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
+
+        // Finish and tidy
+        pkg.revert();
+        tmp.delete();
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java
index 37deba5..fd494ba 100644
--- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java
+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java
@@ -18,6 +18,8 @@
 

 import static org.junit.Assert.assertArrayEquals;

 import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertNull;

 import static org.junit.Assert.assertTrue;

 

 import java.io.ByteArrayInputStream;

@@ -32,6 +34,8 @@
 import javax.crypto.Cipher;

 

 import org.apache.poi.POIDataSamples;

+import org.apache.poi.openxml4j.opc.ContentTypes;

+import org.apache.poi.openxml4j.opc.OPCPackage;

 import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader;

 import org.apache.poi.poifs.filesystem.DirectoryNode;

 import org.apache.poi.poifs.filesystem.DocumentNode;

@@ -107,7 +111,7 @@
         long decPackLenExpected = decExpected.getLength();

         assertEquals(decPackLenExpected, payloadExpected.length);

 

-        is = nfs.getRoot().createDocumentInputStream("EncryptedPackage");

+        is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY);

         is = new BoundedInputStream(is, is.available()-16); // ignore padding block

         byte encPackExpected[] = IOUtils.toByteArray(is);

         is.close();

@@ -159,7 +163,7 @@
         

         long decPackLenActual = decActual.getLength();

         

-        is = nfs.getRoot().createDocumentInputStream("EncryptedPackage");

+        is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY);

         is = new BoundedInputStream(is, is.available()-16); // ignore padding block

         byte encPackActual[] = IOUtils.toByteArray(is);

         is.close();

@@ -266,6 +270,55 @@
         assertArrayEquals(payloadExpected, payloadActual);

     }

     

+    /**

+     * Ensure we can encrypt a package that is missing the Core

+     *  Properties, eg one from dodgy versions of Jasper Reports 

+     * See https://github.com/nestoru/xlsxenc/ and

+     * http://stackoverflow.com/questions/28593223

+     */

+    @Test

+    public void encryptPackageWithoutCoreProperties() throws Exception {

+        // Open our file without core properties

+        File inp = POIDataSamples.getOpenXML4JInstance().getFile("OPCCompliance_NoCoreProperties.xlsx");

+        OPCPackage pkg = OPCPackage.open(inp.getPath());

+        

+        // It doesn't have any core properties yet

+        assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());

+        assertNotNull(pkg.getPackageProperties());

+        assertNotNull(pkg.getPackageProperties().getLanguageProperty());

+        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());

+        

+        // Encrypt it

+        EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);

+        NPOIFSFileSystem fs = new NPOIFSFileSystem();

+        

+        Encryptor enc = info.getEncryptor();

+        enc.confirmPassword("password");

+        OutputStream os = enc.getDataStream(fs);

+        pkg.save(os);

+        pkg.revert();

+        

+        // Save the resulting OLE2 document, and re-open it

+        ByteArrayOutputStream baos = new ByteArrayOutputStream();

+        fs.writeFilesystem(baos);

+        

+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

+        NPOIFSFileSystem inpFS = new NPOIFSFileSystem(bais);

+        

+        // Check we can decrypt it

+        info = new EncryptionInfo(inpFS);

+        Decryptor d = Decryptor.getInstance(info);

+        assertEquals(true, d.verifyPassword("password"));

+        

+        OPCPackage inpPkg = OPCPackage.open(d.getDataStream(inpFS));

+        

+        // Check it now has empty core properties

+        assertEquals(1, inpPkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());

+        assertNotNull(inpPkg.getPackageProperties());

+        assertNotNull(inpPkg.getPackageProperties().getLanguageProperty());

+        assertNull(inpPkg.getPackageProperties().getLanguageProperty().getValue());

+    }

+    

     @Test

     @Ignore

     public void inPlaceRewrite() throws Exception {

diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
index ded14df..d0eeb3d 100644
--- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
@@ -316,7 +316,7 @@
         signatureConfig.addSignatureFacet(new XAdESXLSignatureFacet());

         

         // check for internet, no error means it works

-        boolean mockTsp = (getAccessError("http://timestamp.comodoca.com/rfc3161", true, 10000) == null);

+        boolean mockTsp = (getAccessError("http://timestamp.comodoca.com/rfc3161", true, 10000) != null);

         

         // http://timestamping.edelweb.fr/service/tsp

         // http://tsa.belgium.be/connect

@@ -382,11 +382,13 @@
             si.confirmSignature();

         } catch (RuntimeException e) {

             // only allow a ConnectException because of timeout, we see this in Jenkins from time to time...

-            assertNotNull("Only allowing ConnectException here, but had: " + e, e.getCause());

+            if(e.getCause() == null) {

+                throw e;

+            }

             if(!(e.getCause() instanceof ConnectException)) {

                 throw e;

             }

-            assertTrue("Only allowing ConnectException here, but had: " + e, e.getCause().getMessage().contains("timed out"));

+            assertTrue("Only allowing ConnectException with 'timed out' as message here, but had: " + e, e.getCause().getMessage().contains("timed out"));

         }

         

         // verify

diff --git a/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java b/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java
index 28983ff..f3fcbb8 100644
--- a/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java
+++ b/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java
@@ -17,101 +17,282 @@
 
 package org.apache.poi.ss;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.InputStream;
 
+import org.apache.poi.EmptyFileException;
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.util.TempFile;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 
 import junit.framework.TestCase;
 
 public final class TestWorkbookFactory extends TestCase {
-	private String xls;
-	private String xlsx;
-	private String txt;
+    private String xls;
+    private String xlsx;
+    private String[] xls_prot;
+    private String[] xlsx_prot;
+    private String txt;
 
-	protected void setUp() {
-		xls = "SampleSS.xls";
-		xlsx = "SampleSS.xlsx";
-		txt = "SampleSS.txt";
-	}
+    protected void setUp() {
+        xls = "SampleSS.xls";
+        xlsx = "SampleSS.xlsx";
+        xls_prot = new String[] {"password.xls", "password"};
+        xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"};
+        txt = "SampleSS.txt";
+    }
 
-	public void testCreateNative() throws Exception {
-		Workbook wb;
+    public void testCreateNative() throws Exception {
+        Workbook wb;
 
-		// POIFS -> hssf
-		wb = WorkbookFactory.create(
-				new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream(xls))
-		);
-		assertNotNull(wb);
-		assertTrue(wb instanceof HSSFWorkbook);
-		wb.close();
+        // POIFS -> hssf
+        wb = WorkbookFactory.create(
+                new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream(xls))
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
 
-		// Package -> xssf
-		wb = WorkbookFactory.create(
-				OPCPackage.open(
+        // Package -> xssf
+        wb = WorkbookFactory.create(
+                OPCPackage.open(
                         HSSFTestDataSamples.openSampleFileStream(xlsx))
-		);
-		assertNotNull(wb);
-		assertTrue(wb instanceof XSSFWorkbook);
-		// TODO: this re-writes the sample-file?! wb.close();
-	}
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+        // TODO: this re-writes the sample-file?! wb.close();
+    }
 
-	/**
-	 * Creates the appropriate kind of Workbook, but
-	 *  checking the mime magic at the start of the
-	 *  InputStream, then creating what's required.
-	 */
-	public void testCreateGeneric() throws Exception {
-		Workbook wb;
+    public void testCreateReadOnly() throws Exception {
+        Workbook wb;
 
-		// InputStream -> either
-		wb = WorkbookFactory.create(
-				HSSFTestDataSamples.openSampleFileStream(xls)
-		);
-		assertNotNull(wb);
-		assertTrue(wb instanceof HSSFWorkbook);
-		wb.close();
+        // POIFS -> hssf
+        wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xls), null, true);
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
 
-		wb = WorkbookFactory.create(
-				HSSFTestDataSamples.openSampleFileStream(xlsx)
-		);
-		assertNotNull(wb);
-		assertTrue(wb instanceof XSSFWorkbook);
-		// TODO: this re-writes the sample-file?! wb.close();
-		
-		// File -> either
-      wb = WorkbookFactory.create(
-            HSSFTestDataSamples.getSampleFile(xls)
-      );
-      assertNotNull(wb);
-      assertTrue(wb instanceof HSSFWorkbook);
-      wb.close();
+        // Package -> xssf
+        wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xlsx), null, true);
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+        wb.close();
+    }
 
-      wb = WorkbookFactory.create(
-            HSSFTestDataSamples.getSampleFile(xlsx)
-      );
-      assertNotNull(wb);
-      assertTrue(wb instanceof XSSFWorkbook);
-      
-      // TODO: close() re-writes the sample-file?! Resort to revert() for now to close file handle...
-      ((XSSFWorkbook)wb).getPackage().revert();
+    /**
+     * Creates the appropriate kind of Workbook, but
+     *  checking the mime magic at the start of the
+     *  InputStream, then creating what's required.
+     */
+    public void testCreateGeneric() throws Exception {
+        Workbook wb;
 
-		// Invalid type -> exception
-		try {
-			InputStream stream = HSSFTestDataSamples.openSampleFileStream(txt);
-			try {
+        // InputStream -> either
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xls)
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xlsx)
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+        // TODO: this re-writes the sample-file?! wb.close();
+
+        // File -> either
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xls)
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xlsx)
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+        // TODO: close() re-writes the sample-file?! Resort to revert() for now to close file handle...
+        ((XSSFWorkbook)wb).getPackage().revert();
+
+        // Invalid type -> exception
+        try {
+            InputStream stream = HSSFTestDataSamples.openSampleFileStream(txt);
+            try {
                 wb = WorkbookFactory.create(stream);
-			} finally {
-			    stream.close();
-			}
-			fail();
-		} catch(IllegalArgumentException e) {
-			// Good
-		}
-	}
+            } finally {
+                stream.close();
+            }
+            fail();
+        } catch(IllegalArgumentException e) {
+            // Good
+        }
+    }
+
+    /**
+     * Check that the overloaded stream methods which take passwords work properly
+     */
+    public void testCreateWithPasswordFromStream() throws Exception {
+        Workbook wb;
+
+
+        // Unprotected, no password given, opens normally
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xls), null
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xlsx), null
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Unprotected, wrong password, opens normally
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xls), "wrong"
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xlsx), "wrong"
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Protected, correct password, opens fine
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1]
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1]
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Protected, wrong password, throws Exception
+        try {
+            wb = WorkbookFactory.create(
+                    HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), "wrong"
+            );
+            fail("Shouldn't be able to open with the wrong password");
+        } catch (EncryptedDocumentException e) {}
+
+        try {
+            wb = WorkbookFactory.create(
+                    HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), "wrong"
+            );
+            fail("Shouldn't be able to open with the wrong password");
+        } catch (EncryptedDocumentException e) {}
+    }
+
+    /**
+     * Check that the overloaded file methods which take passwords work properly
+     */
+    public void testCreateWithPasswordFromFile() throws Exception {
+        Workbook wb;
+
+        // Unprotected, no password given, opens normally
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xls), null
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xlsx), null
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Unprotected, wrong password, opens normally
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xls), "wrong"
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xlsx), "wrong"
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Protected, correct password, opens fine
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1]
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof HSSFWorkbook);
+        wb.close();
+
+        wb = WorkbookFactory.create(
+                HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1]
+        );
+        assertNotNull(wb);
+        assertTrue(wb instanceof XSSFWorkbook);
+
+
+        // Protected, wrong password, throws Exception
+        try {
+            wb = WorkbookFactory.create(
+                    HSSFTestDataSamples.getSampleFile(xls_prot[0]), "wrong"
+            );
+            fail("Shouldn't be able to open with the wrong password");
+        } catch (EncryptedDocumentException e) {}
+
+        try {
+            wb = WorkbookFactory.create(
+                    HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), "wrong"
+            );
+            fail("Shouldn't be able to open with the wrong password");
+        } catch (EncryptedDocumentException e) {}
+    }
+    
+    /**
+     * Check that a helpful exception is given on an empty file / stream
+     */
+    public void testEmptyFile() throws Exception {
+        InputStream emptyStream = new ByteArrayInputStream(new byte[0]);
+        File emptyFile = TempFile.createTempFile("empty", ".poi");
+        
+        try {
+            WorkbookFactory.create(emptyStream);
+            fail("Shouldn't be able to create for an empty stream");
+        } catch (EmptyFileException e) {
+        }
+        
+        try {
+            WorkbookFactory.create(emptyFile);
+            fail("Shouldn't be able to create for an empty file");
+        } catch (EmptyFileException e) {
+        }
+        emptyFile.delete();
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java b/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java
new file mode 100644
index 0000000..f90c653
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/ss/formula/TestFormulaParser.java
@@ -0,0 +1,66 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+package org.apache.poi.ss.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import junit.framework.TestCase;
+
+/**
+ * Test {@link FormulaParser}'s handling of row numbers at the edge of the
+ * HSSF/XSSF ranges.
+ * 
+ * @author David North
+ */
+public class TestFormulaParser extends TestCase {
+
+    public void testHSSFFailsForOver65536() {
+        FormulaParsingWorkbook workbook = HSSFEvaluationWorkbook.create(new HSSFWorkbook());
+        try {
+            FormulaParser.parse("Sheet1!1:65537", workbook, FormulaType.CELL, 0);
+            fail("Expected exception");
+        }
+        catch (FormulaParseException expected) {
+        }
+    }
+
+    public void testHSSFPassCase() {
+        FormulaParsingWorkbook workbook = HSSFEvaluationWorkbook.create(new HSSFWorkbook());
+        FormulaParser.parse("Sheet1!1:65536", workbook, FormulaType.CELL, 0);
+    }
+
+    public void testXSSFWorksForOver65536() {
+        FormulaParsingWorkbook workbook = XSSFEvaluationWorkbook.create(new XSSFWorkbook());
+        FormulaParser.parse("Sheet1!1:65537", workbook, FormulaType.CELL, 0);
+    }
+
+    public void testXSSFFailCase() {
+        FormulaParsingWorkbook workbook = XSSFEvaluationWorkbook.create(new XSSFWorkbook());
+        try {
+            FormulaParser.parse("Sheet1!1:1048577", workbook, FormulaType.CELL, 0); // one more than max rows.
+            fail("Expected exception");
+        }
+        catch (FormulaParseException expected) {
+        }
+    }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java
index ba55f07..f78819c 100644
--- a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java
+++ b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java
@@ -19,6 +19,7 @@
 
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.ss.ITestDataProvider;
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.xssf.SXSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.streaming.SXSSFCell;
@@ -48,32 +49,5 @@
 
         // invalid characters are replaced with question marks
         assertEquals("???<>\t\n\u00a0 &\"POI\'\u2122", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
-
-    }
-
-    public void testEncodingbeloAscii(){
-        Workbook xwb = XSSFITestDataProvider.instance.createWorkbook();
-        Cell xCell = xwb.createSheet().createRow(0).createCell(0);
-
-        Workbook swb = SXSSFITestDataProvider.instance.createWorkbook();
-        Cell sCell = swb.createSheet().createRow(0).createCell(0);
-
-        StringBuffer sb = new StringBuffer();
-        // test all possible characters
-        for(int i = 0; i < Character.MAX_VALUE; i++) sb.append((char)i) ;
-
-        String str = sb.toString();
-
-        xCell.setCellValue(str);
-        assertEquals(str, xCell.getStringCellValue());
-        sCell.setCellValue(str);
-        assertEquals(str, sCell.getStringCellValue());
-
-        xwb = XSSFITestDataProvider.instance.writeOutAndReadBack(xwb);
-        swb = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb);
-        xCell = xwb.getSheetAt(0).createRow(0).createCell(0);
-        sCell = swb.getSheetAt(0).createRow(0).createCell(0);
-
-        assertEquals(xCell.getStringCellValue(), sCell.getStringCellValue());
     }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
index 6d66cae..35f30a3 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
@@ -18,6 +18,7 @@
 
 import static junit.framework.TestCase.assertEquals;
 import static org.apache.poi.POITestCase.assertContains;
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
@@ -47,7 +48,6 @@
 import org.apache.poi.xslf.usermodel.XSLFSlideLayout;
 import org.junit.Ignore;
 import org.junit.Test;
-
 public class TestXSLFBugs {
 
     @Test
@@ -196,7 +196,7 @@
     }
 
     @Test
-    // @Ignore("Similar to TestFontRendering it doesn't make sense to compare images because of tiny rendering differences in windows/unix")
+    @Ignore("Similar to TestFontRendering it doesn't make sense to compare images because of tiny rendering differences in windows/unix")
     public void bug54542() throws Exception {
         XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("54542_cropped_bitmap.pptx");
         
@@ -259,6 +259,107 @@
         ss.setSlideOrder(slide, 2);
         validateSlides(ss, true, "Slide1","Slide2","New slide");
     }
+    
+    /**
+     * When working with >9 images, make sure the sorting ensures
+     *  that image10.foo isn't between image1.foo and image2.foo
+     */
+    @Test
+    public void test57552() throws Exception {
+        XMLSlideShow ss = new XMLSlideShow();
+        for (String s : new String[]{"Slide1","Slide2"}) {
+            ss.createSlide().createTextBox().setText(s);
+        }
+        
+        // Slide starts with just layout relation
+        XSLFSlide slide = ss.getSlides().get(0);
+        assertEquals(0, ss.getAllPictures().size());
+        assertEquals(1, slide.getShapes().size());
+        
+        assertEquals(1, slide.getRelations().size());
+        assertRelationEquals(XSLFRelation.SLIDE_LAYOUT, slide.getRelations().get(0));
+        
+        // Some dummy pictures
+        byte[][] pics = new byte[15][3];
+        for (int i=0; i<pics.length; i++) {
+            for (int j=0; j<pics[i].length; j++) {
+                pics[i][j] = (byte)i;
+            }
+        }
+        
+        // Add a few pictures
+        for (int i=0; i<10; i++) {
+            int idx = ss.addPicture(pics[i], XSLFPictureData.PICTURE_TYPE_JPEG);
+            assertEquals(i, idx);
+            assertEquals(i+1, ss.getAllPictures().size());
+            
+            XSLFPictureShape shape = slide.createPicture(idx);
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(pics[i], shape.getPictureData().getData());
+            assertEquals(i+2, slide.getShapes().size());
+        }
+        // Re-fetch the pictures and check
+        for (int i=0; i<10; i++) {
+            XSLFPictureShape shape = (XSLFPictureShape)slide.getShapes().get(i+1);
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(pics[i], shape.getPictureData().getData());
+        }
+        
+        // Add past 10
+        for (int i=10; i<15; i++) {
+            int idx = ss.addPicture(pics[i], XSLFPictureData.PICTURE_TYPE_JPEG);
+            assertEquals(i, idx);
+            assertEquals(i+1, ss.getAllPictures().size());
+            
+            XSLFPictureShape shape = slide.createPicture(idx);
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(pics[i], shape.getPictureData().getData());
+            assertEquals(i+2, slide.getShapes().size());
+        }
+        // Check all pictures
+        for (int i=0; i<15; i++) {
+            XSLFPictureShape shape = (XSLFPictureShape)slide.getShapes().get(i+1);
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(pics[i], shape.getPictureData().getData());
+        }
+        
+        // Add a duplicate, check the right one is picked
+        int idx = ss.addPicture(pics[3], XSLFPictureData.PICTURE_TYPE_JPEG);
+        assertEquals(3, idx);
+        assertEquals(15, ss.getAllPictures().size());
+        
+        XSLFPictureShape shape = slide.createPicture(idx);
+        assertNotNull(shape.getPictureData());
+        assertArrayEquals(pics[3], shape.getPictureData().getData());
+        assertEquals(17, slide.getShapes().size());
+        
+        
+        // Save and re-load
+        ss = XSLFTestDataSamples.writeOutAndReadBack(ss);
+        slide = ss.getSlides().get(0);
+        
+        // Check the 15 individual ones added
+        for (int i=0; i<15; i++) {
+            shape = (XSLFPictureShape)slide.getShapes().get(i+1);
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(pics[i], shape.getPictureData().getData());
+        }
+        
+        // Check the duplicate
+        shape = (XSLFPictureShape)slide.getShapes().get(16);
+        assertNotNull(shape.getPictureData());
+        assertArrayEquals(pics[3], shape.getPictureData().getData());
+        
+        // Add another duplicate
+        idx = ss.addPicture(pics[5], XSLFPictureData.PICTURE_TYPE_JPEG);
+        assertEquals(5, idx);
+        assertEquals(15, ss.getAllPictures().size());
+        
+        shape = slide.createPicture(idx);
+        assertNotNull(shape.getPictureData());
+        assertArrayEquals(pics[5], shape.getPictureData().getData());
+        assertEquals(18, slide.getShapes().size());
+    }
 
     private void validateSlides(XMLSlideShow ss, boolean saveAndReload, String... slideTexts) {
         if (saveAndReload) {
@@ -272,5 +373,8 @@
             assertContains(getSlideText(slide), slideTexts[i]);
         }
     }
-
+    private void assertRelationEquals(XSLFRelation expected, POIXMLDocumentPart relation) {
+        assertEquals(expected.getContentType(), relation.getPackagePart().getContentType());
+        assertEquals(expected.getFileName(expected.getFileNameIndex(relation)), relation.getPackagePart().getPartName().getName());
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java b/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java
index cacf837..953b6a1 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java
@@ -41,7 +41,7 @@
 
     public XSSFWorkbook writeOutAndReadBack(Workbook original) {
         if(!(original instanceof XSSFWorkbook)) {
-            throw new IllegalArgumentException("Expected an instance of XSSFWorkbook");
+            throw new IllegalArgumentException("Expected an instance of XSSFWorkbook, but had " + original.getClass());
         }
         return XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)original);
     }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java b/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java
index e48787b..b56b379 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFEventBasedExcelExtractor.java
@@ -23,6 +23,7 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.POITextExtractor;
+import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.extractor.ExcelExtractor;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -155,7 +156,6 @@
 		POITextExtractor[] extractors =
 			new POITextExtractor[] { ooxmlExtractor, ole2Extractor };
 		for (int i = 0; i < extractors.length; i++) {
-			@SuppressWarnings("resource")
             POITextExtractor extractor = extractors[i];
 			
 			String text = extractor.getText().replaceAll("[\r\t]", "");
@@ -316,4 +316,25 @@
             fixture.close();
         }
     }
+    
+    public void testFile56278_normal() throws Exception {
+        // first with normal Text Extractor
+        POIXMLTextExtractor extractor = new XSSFExcelExtractor(
+                XSSFTestDataSamples.openSampleWorkbook("56278.xlsx"));
+        try {
+            assertNotNull(extractor.getText());
+        } finally {
+            extractor.close();
+        }
+    }
+    
+    public void testFile56278_event() throws Exception {
+        // then with event based one
+        POIXMLTextExtractor extractor = getExtractor("56278.xlsx");        
+        try {
+            assertNotNull(extractor.getText());
+        } finally {
+            extractor.close();
+        }
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
index 2cf6609..ad3c443 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
@@ -89,6 +89,13 @@
         super.bug35084();
     }
 
+    @Test
+    public void getCellComment() throws IOException {
+    	// TODO: reading cell comments via Sheet does not work currently as it tries 
+    	// to access the underlying sheet for this, but comments are stored as
+    	// properties on Cells...
+    }
+    
     @Override
     @Test
     public void defaultColumnStyle() {
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java
index ce217e2..7aa9422 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java
@@ -88,19 +88,23 @@
     }
 
     @Test
-    public void existingWorkbook() {
+    public void existingWorkbook() throws IOException {
     	XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
     	xssfWorkbook.createSheet("S1");
     	SXSSFWorkbook wb = new SXSSFWorkbook(xssfWorkbook);
-    	xssfWorkbook = (XSSFWorkbook) SXSSFITestDataProvider.instance.writeOutAndReadBack(wb);
-    	assertTrue(wb.dispose());
-
-        wb = new SXSSFWorkbook(xssfWorkbook);
-    	assertEquals(1, wb.getNumberOfSheets());
-    	Sheet sheet  = wb.getSheetAt(0);
-    	assertNotNull(sheet);
-    	assertEquals("S1", sheet.getSheetName());
-        assertTrue(wb.dispose());
+    	try {
+        	xssfWorkbook = (XSSFWorkbook) SXSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+        	assertTrue(wb.dispose());
+    
+            wb = new SXSSFWorkbook(xssfWorkbook);
+        	assertEquals(1, wb.getNumberOfSheets());
+        	Sheet sheet  = wb.getSheetAt(0);
+        	assertNotNull(sheet);
+        	assertEquals("S1", sheet.getSheetName());
+    	} finally {
+    	    assertTrue(wb.dispose());
+    	    wb.close();
+    	}
 
     }
 
@@ -123,7 +127,7 @@
         XSSFWorkbook xssfWorkbook = (XSSFWorkbook) SXSSFITestDataProvider.instance.writeOutAndReadBack(wb);
         sss = (SharedStringsTable)f.get(wb);
         assertEquals(2, sss.getUniqueCount());
-        wb.dispose();
+        assertTrue(wb.dispose());
 
         Sheet sheet1 = xssfWorkbook.getSheetAt(0);
         assertEquals("S1", sheet1.getSheetName());
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java
new file mode 100644
index 0000000..7a28795
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java
@@ -0,0 +1,82 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+

+package org.apache.poi.xssf.usermodel;

+

+import static org.junit.Assert.assertEquals;

+

+import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;

+import org.apache.poi.ss.usermodel.PrintSetup;

+import org.apache.poi.ss.usermodel.Sheet;

+import org.apache.poi.ss.usermodel.Workbook;

+import org.apache.poi.xssf.SXSSFITestDataProvider;

+import org.apache.poi.xssf.streaming.SXSSFWorkbook;

+import org.junit.Ignore;

+import org.junit.Test;

+

+public final class TestSXSSFBugs extends BaseTestBugzillaIssues {

+    public TestSXSSFBugs() {

+        super(SXSSFITestDataProvider.instance);

+    }

+

+    // override some tests which do not work for SXSSF

+    @Override @Ignore("cloneSheet() not implemented") @Test public void bug18800() { /* cloneSheet() not implemented */ }

+    @Override @Ignore("cloneSheet() not implemented") @Test public void bug22720() { /* cloneSheet() not implemented */ }

+    @Override @Ignore("Evaluation is not supported") @Test public void bug43093() { /* Evaluation is not supported */ }

+    @Override @Ignore("Evaluation is not supported") @Test public void bug51024() { /* Evaluation is not supported */ }

+    @Override @Ignore("Evaluation is not supported") @Test public void bug46729_testMaxFunctionArguments() { /* Evaluation is not supported */ }

+    @Override @Ignore("Evaluation is not supported") @Test public void stackoverflow26437323() { /* Evaluation is not supported */ }

+    @Override @Ignore("Evaluation is not supported") @Test public void bug47815() { /* Evaluation is not supported */ }

+    

+    /**

+     * Setting repeating rows and columns shouldn't break

+     *  any print settings that were there before

+     */

+    @SuppressWarnings("deprecation")

+    @Test

+    public void bug49253() throws Exception {

+        Workbook wb1 = new SXSSFWorkbook();

+        Workbook wb2 = new SXSSFWorkbook();

+

+        // No print settings before repeating

+        Sheet s1 = wb1.createSheet(); 

+

+        wb1.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);

+

+        PrintSetup ps1 = s1.getPrintSetup();

+        assertEquals(false, ps1.getValidSettings());

+        assertEquals(false, ps1.getLandscape());

+

+

+        // Had valid print settings before repeating

+        Sheet s2 = wb2.createSheet();

+        PrintSetup ps2 = s2.getPrintSetup();

+

+        ps2.setLandscape(false);

+        assertEquals(true, ps2.getValidSettings());

+        assertEquals(false, ps2.getLandscape());

+

+        wb2.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);

+

+        ps2 = s2.getPrintSetup();

+        assertEquals(true, ps2.getValidSettings());

+        assertEquals(false, ps2.getLandscape());

+

+        wb1.close();

+        wb2.close();

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java
index c90ba80..83004cb 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java
@@ -17,9 +17,11 @@
 

 package org.apache.poi.xssf.usermodel;

 

-import static org.junit.Assert.assertEquals;

-

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.FileOutputStream;

 import java.io.IOException;

+import java.io.OutputStream;

 import java.nio.charset.Charset;

 import java.util.Calendar;

 import java.util.Date;

@@ -29,17 +31,21 @@
 

 import org.apache.poi.hssf.HSSFTestDataSamples;

 import org.apache.poi.ss.usermodel.Cell;

+import org.apache.poi.ss.usermodel.CellStyle;

 import org.apache.poi.ss.usermodel.DataFormatter;

 import org.apache.poi.ss.usermodel.DateUtil;

-import org.apache.poi.ss.usermodel.FormulaError;

 import org.apache.poi.ss.usermodel.RichTextString;

 import org.apache.poi.ss.usermodel.Row;

 import org.apache.poi.ss.usermodel.Sheet;

 import org.apache.poi.ss.usermodel.Workbook;

+import org.apache.poi.ss.util.CellRangeAddress;

+import org.apache.poi.ss.util.CellUtil;

+import org.apache.poi.ss.util.RegionUtil;

 import org.apache.poi.xssf.SXSSFITestDataProvider;

 import org.apache.poi.xssf.XSSFTestDataSamples;

 import org.apache.poi.xssf.streaming.SXSSFWorkbook;

 import org.junit.Test;

+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;

 

 /**

  * @author centic

@@ -184,38 +190,6 @@
         }

     }

 

-    

-    @Test

-    public void test57165() throws IOException {

-        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");

-        try {

-            removeAllSheetsBut(3, wb);

-            wb.cloneSheet(0); // Throws exception here

-            wb.setSheetName(1, "New Sheet");

-            //saveWorkbook(wb, fileName);

-            

-            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);

-            try {

-                

-            } finally {

-                wbBack.close();

-            }

-        } finally {

-            wb.close();

-        }

-    }

-

-    private static void removeAllSheetsBut(int sheetIndex, Workbook wb)

-    {

-        int sheetNb = wb.getNumberOfSheets();

-        // Move this sheet at the first position

-        wb.setSheetOrder(wb.getSheetName(sheetIndex), 0);

-        for (int sn = sheetNb - 1; sn > 0; sn--)

-        {

-            wb.removeSheetAt(sn);

-        }

-    }

-

     // When this is fixed, the test case should go to BaseTestXCell with 

     // adjustments to use _testDataProvider to also verify this for XSSF

     public void testBug57294() throws IOException {

@@ -244,65 +218,159 @@
         assertEquals(4, strBack.getIndexOfFormattingRun(2));

     }

 

-    @Test

-    public void testBug56655() {

-        XSSFWorkbook wb =  new XSSFWorkbook();

-        Sheet sheet = wb.createSheet();

-        

-        setCellFormula(sheet, 0, 0, "#VALUE!");

-        setCellFormula(sheet, 0, 1, "SUMIFS(A:A,A:A,#VALUE!)");

+   @Test

+   public void testBug55752() throws IOException {

+       Workbook wb = new XSSFWorkbook();

+       try {

+           Sheet sheet = wb.createSheet("test");

+    

+           for (int i = 0; i < 4; i++) {

+               Row row = sheet.createRow(i);

+               for (int j = 0; j < 2; j++) {

+                   Cell cell = row.createCell(j);

+                   cell.setCellStyle(wb.createCellStyle());

+               }

+           }

+    

+           // set content

+           Row row1 = sheet.getRow(0);

+           row1.getCell(0).setCellValue("AAA");

+           Row row2 = sheet.getRow(1);

+           row2.getCell(0).setCellValue("BBB");

+           Row row3 = sheet.getRow(2);

+           row3.getCell(0).setCellValue("CCC");

+           Row row4 = sheet.getRow(3);

+           row4.getCell(0).setCellValue("DDD");

+    

+           // merge cells

+           CellRangeAddress range1 = new CellRangeAddress(0, 0, 0, 1);

+           sheet.addMergedRegion(range1);

+           CellRangeAddress range2 = new CellRangeAddress(1, 1, 0, 1);

+           sheet.addMergedRegion(range2);

+           CellRangeAddress range3 = new CellRangeAddress(2, 2, 0, 1);

+           sheet.addMergedRegion(range3);

+           assertEquals(0, range3.getFirstColumn());

+           assertEquals(1, range3.getLastColumn());

+           assertEquals(2, range3.getLastRow());

+           CellRangeAddress range4 = new CellRangeAddress(3, 3, 0, 1);

+           sheet.addMergedRegion(range4);

+           

+           // set border

+           RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, range1, sheet, wb);

+           

+           row2.getCell(0).getCellStyle().setBorderBottom(CellStyle.BORDER_THIN);

+           row2.getCell(1).getCellStyle().setBorderBottom(CellStyle.BORDER_THIN);

 

-        XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);

+           Cell cell0 = CellUtil.getCell(row3, 0);

+           CellUtil.setCellStyleProperty(cell0, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN);

+           Cell cell1 = CellUtil.getCell(row3, 1);

+           CellUtil.setCellStyleProperty(cell1, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN);

 

-        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0,0).getCachedFormulaResultType());

-        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,0).getErrorCellValue());

-        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0,1).getCachedFormulaResultType());

-        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,1).getErrorCellValue());

-    }

-

-    @Test

-    public void testBug56655a() {

-        XSSFWorkbook wb =  new XSSFWorkbook();

-        Sheet sheet = wb.createSheet();

-        

-        setCellFormula(sheet, 0, 0, "B1*C1");

-        sheet.getRow(0).createCell(1).setCellValue("A");

-        setCellFormula(sheet, 1, 0, "B1*C1");

-        sheet.getRow(1).createCell(1).setCellValue("A");

-        setCellFormula(sheet, 0, 3, "SUMIFS(A:A,A:A,A2)");

-

-        XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);

-

-        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0, 0).getCachedFormulaResultType());

-        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 0).getErrorCellValue());

-        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 1, 0).getCachedFormulaResultType());

-        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 1, 0).getErrorCellValue());

-        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0, 3).getCachedFormulaResultType());

-        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 3).getErrorCellValue());

-    }

-

-    /**

-    * @param row 0-based

-    * @param column 0-based

-    */

-   void setCellFormula(Sheet sheet, int row, int column, String formula) {

-       Row r = sheet.getRow(row);

-       if (r == null) {

-           r = sheet.createRow(row);

+           RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, range4, sheet, wb);

+    

+           // write to file

+           OutputStream stream = new FileOutputStream(new File("C:/temp/55752.xlsx"));

+           try {

+               wb.write(stream);

+           } finally {

+               stream.close();

+           }

+       } finally {

+           wb.close();

        }

-       Cell cell = r.getCell(column);

-       if (cell == null) {

-           cell = r.createCell(column);

-       }

-       cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);

-       cell.setCellFormula(formula);

    }

 

-   /**

-    * @param rowNo 0-based

-    * @param column 0-based

-    */

-   Cell getCell(Sheet sheet, int rowNo, int column) {

-       return sheet.getRow(rowNo).getCell(column);

+   @Test

+   public void test57423() throws IOException {        

+       Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57423.xlsx");

+       

+       Sheet testSheet = wb.getSheetAt(0);

+

+       // row shift (negative or positive) causes corrupted output xlsx file when the shift value is bigger 

+       // than the number of rows being shifted 

+       // Excel 2010 on opening the output file says:

+       // "Excel found unreadable content" and offers recovering the file by removing the unreadable content

+       // This can be observed in cases like the following:

+       // negative shift of 1 row by less than -1

+       // negative shift of 2 rows by less than -2

+       // positive shift of 1 row by 2 or more 

+       // positive shift of 2 rows by 3 or more

+       

+       //testSheet.shiftRows(4, 5, -3);

+       testSheet.shiftRows(10, 10, 2);

+       

+       checkRows57423(testSheet);

+       

+       Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);

+

+       /*FileOutputStream stream = new FileOutputStream("C:\\temp\\57423.xlsx");

+       try {

+           wb.write(stream);

+       } finally {

+           stream.close();

+       }*/

+

+       wb.close();

+       

+       checkRows57423(wbBack.getSheetAt(0));

+       

+       wbBack.close();

+   }

+

+   private void checkRows57423(Sheet testSheet) throws IOException {

+       checkRow57423(testSheet, 0, "0");

+       checkRow57423(testSheet, 1, "1");

+       checkRow57423(testSheet, 2, "2");

+       checkRow57423(testSheet, 3, "3");

+       checkRow57423(testSheet, 4, "4");

+       checkRow57423(testSheet, 5, "5");

+       checkRow57423(testSheet, 6, "6");

+       checkRow57423(testSheet, 7, "7");

+       checkRow57423(testSheet, 8, "8");

+       checkRow57423(testSheet, 9, "9");

+       

+       assertNull("Row number 10 should be gone after the shift", 

+               testSheet.getRow(10));

+       

+       checkRow57423(testSheet, 11, "11");

+       checkRow57423(testSheet, 12, "10");

+       checkRow57423(testSheet, 13, "13");

+       checkRow57423(testSheet, 14, "14");

+       checkRow57423(testSheet, 15, "15");

+       checkRow57423(testSheet, 16, "16");

+       checkRow57423(testSheet, 17, "17");

+       checkRow57423(testSheet, 18, "18");

+       

+       ByteArrayOutputStream stream = new ByteArrayOutputStream();

+       try {

+           ((XSSFSheet)testSheet).write(stream);

+       } finally {

+           stream.close();

+       }

+       

+       // verify that the resulting XML has the rows in correct order as required by Excel

+       String xml = new String(stream.toByteArray());

+       int posR12 = xml.indexOf("<row r=\"12\"");

+       int posR13 = xml.indexOf("<row r=\"13\"");

+       

+       // both need to be found

+       assertTrue(posR12 != -1);

+       assertTrue(posR13 != -1);

+       

+       assertTrue("Need to find row 12 before row 13 after the shifting, but had row 12 at " + posR12 + " and row 13 at " + posR13, 

+               posR12 < posR13);

+   }

+

+   private void checkRow57423(Sheet testSheet, int rowNum, String contents) {

+       Row row = testSheet.getRow(rowNum);

+       assertNotNull("Expecting row at rownum " + rowNum, row);

+       

+       CTRow ctRow = ((XSSFRow)row).getCTRow();

+       assertEquals(rowNum+1, ctRow.getR());

+       

+       Cell cell = row.getCell(0);

+       assertNotNull("Expecting cell at rownum " + rowNum, cell);

+       assertEquals("Did not have expected contents at rownum " + rowNum, 

+               contents + ".0", cell.toString());

    }

 }

diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
index e2f0305..646fe8e 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
@@ -17,7 +17,13 @@
 
 package org.apache.poi.xssf.usermodel;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -25,8 +31,12 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.POIDataSamples;
@@ -48,7 +58,27 @@
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.Function;
-import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.CellValue;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.DataFormatter;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.usermodel.Hyperlink;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Name;
+import org.apache.poi.ss.usermodel.PrintSetup;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
@@ -61,6 +91,7 @@
 import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
@@ -68,7 +99,6 @@
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl;
 
 public final class TestXSSFBugs extends BaseTestBugzillaIssues {
-
     public TestXSSFBugs() {
         super(XSSFITestDataProvider.instance);
     }
@@ -182,7 +212,7 @@
         assertEquals(1, rels.size());
         assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment());
     }
-    
+
     /**
      * Excel will sometimes write a button with a textbox
      *  containing &gt;br&lt; (not closed!).
@@ -191,7 +221,7 @@
      */
     @Test
     public void bug49020() throws Exception {
-       /*XSSFWorkbook wb =*/ XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx");
+        /*XSSFWorkbook wb =*/ XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx");
     }
 
     /**
@@ -203,42 +233,42 @@
         CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet();
         assertNotNull(sh.getPhoneticPr());
     }
-    
+
     /**
      * Names which are defined with a Sheet
      *  should return that sheet index properly 
      */
     @Test
     public void bug48923() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48923.xlsx");
-       assertEquals(4, wb.getNumberOfNames());
-       
-       Name b1 = wb.getName("NameB1");
-       Name b2 = wb.getName("NameB2");
-       Name sheet2 = wb.getName("NameSheet2");
-       Name test = wb.getName("Test");
-       
-       assertNotNull(b1);
-       assertEquals("NameB1", b1.getNameName());
-       assertEquals("Sheet1", b1.getSheetName());
-       assertEquals(-1, b1.getSheetIndex());
-       
-       assertNotNull(b2);
-       assertEquals("NameB2", b2.getNameName());
-       assertEquals("Sheet1", b2.getSheetName());
-       assertEquals(-1, b2.getSheetIndex());
-       
-       assertNotNull(sheet2);
-       assertEquals("NameSheet2", sheet2.getNameName());
-       assertEquals("Sheet2", sheet2.getSheetName());
-       assertEquals(-1, sheet2.getSheetIndex());
-       
-       assertNotNull(test);
-       assertEquals("Test", test.getNameName());
-       assertEquals("Sheet1", test.getSheetName());
-       assertEquals(-1, test.getSheetIndex());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48923.xlsx");
+        assertEquals(4, wb.getNumberOfNames());
+
+        Name b1 = wb.getName("NameB1");
+        Name b2 = wb.getName("NameB2");
+        Name sheet2 = wb.getName("NameSheet2");
+        Name test = wb.getName("Test");
+
+        assertNotNull(b1);
+        assertEquals("NameB1", b1.getNameName());
+        assertEquals("Sheet1", b1.getSheetName());
+        assertEquals(-1, b1.getSheetIndex());
+
+        assertNotNull(b2);
+        assertEquals("NameB2", b2.getNameName());
+        assertEquals("Sheet1", b2.getSheetName());
+        assertEquals(-1, b2.getSheetIndex());
+
+        assertNotNull(sheet2);
+        assertEquals("NameSheet2", sheet2.getNameName());
+        assertEquals("Sheet2", sheet2.getSheetName());
+        assertEquals(-1, sheet2.getSheetIndex());
+
+        assertNotNull(test);
+        assertEquals("Test", test.getNameName());
+        assertEquals("Sheet1", test.getSheetName());
+        assertEquals(-1, test.getSheetIndex());
     }
-    
+
     /**
      * Problem with evaluation formulas due to
      *  NameXPtgs.
@@ -249,211 +279,108 @@
      */
     @Test
     public void bug48539() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx");
-       assertEquals(3, wb.getNumberOfSheets());
-       assertEquals(0, wb.getNumberOfNames());
-       
-       // Try each cell individually
-       XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
-       for(int i=0; i<wb.getNumberOfSheets(); i++) {
-          Sheet s = wb.getSheetAt(i);
-          for(Row r : s) {
-             for(Cell c : r) {
-                if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
-                    String formula = c.getCellFormula();
-                    CellValue cv;
-                    try {
-                        cv = eval.evaluate(c);
-                    } catch (Exception e) {
-                        throw new RuntimeException("Can't evaluate formula: " + formula, e);
-                    }
-                    
-                    if(cv.getCellType() == Cell.CELL_TYPE_NUMERIC) {
-                        // assert that the calculated value agrees with
-                        // the cached formula result calculated by Excel
-                        double cachedFormulaResult = c.getNumericCellValue();
-                        double evaluatedFormulaResult = cv.getNumberValue();
-                        assertEquals(c.getCellFormula(), cachedFormulaResult, evaluatedFormulaResult, 1E-7);
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx");
+        assertEquals(3, wb.getNumberOfSheets());
+        assertEquals(0, wb.getNumberOfNames());
+
+        // Try each cell individually
+        XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
+        for(int i=0; i<wb.getNumberOfSheets(); i++) {
+            Sheet s = wb.getSheetAt(i);
+            for(Row r : s) {
+                for(Cell c : r) {
+                    if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+                        String formula = c.getCellFormula();
+                        CellValue cv;
+                        try {
+                            cv = eval.evaluate(c);
+                        } catch (Exception e) {
+                            throw new RuntimeException("Can't evaluate formula: " + formula, e);
+                        }
+
+                        if(cv.getCellType() == Cell.CELL_TYPE_NUMERIC) {
+                            // assert that the calculated value agrees with
+                            // the cached formula result calculated by Excel
+                            double cachedFormulaResult = c.getNumericCellValue();
+                            double evaluatedFormulaResult = cv.getNumberValue();
+                            assertEquals(c.getCellFormula(), cachedFormulaResult, evaluatedFormulaResult, 1E-7);
+                        }
                     }
                 }
-             }
-          }
-       }
-       
-       // Now all of them
+            }
+        }
+
+        // Now all of them
         XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
     }
-    
+
     /**
      * Foreground colours should be found even if
      *  a theme is used 
      */
     @Test
     public void bug48779() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
-       XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
-       XSSFCellStyle cs = cell.getCellStyle();
-       
-       assertNotNull(cs);
-       assertEquals(1, cs.getIndex());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
+        XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
+        XSSFCellStyle cs = cell.getCellStyle();
 
-       // Look at the low level xml elements
-       assertEquals(2, cs.getCoreXf().getFillId());
-       assertEquals(0, cs.getCoreXf().getXfId());
-       assertEquals(true, cs.getCoreXf().getApplyFill());
-       
-       XSSFCellFill fg = wb.getStylesSource().getFillAt(2);
-       assertEquals(0, fg.getFillForegroundColor().getIndexed());
-       assertEquals(0.0, fg.getFillForegroundColor().getTint(), 0);
-       assertEquals("FFFF0000", fg.getFillForegroundColor().getARGBHex());
-       assertEquals(64, fg.getFillBackgroundColor().getIndexed());
-       
-       // Now look higher up
-       assertNotNull(cs.getFillForegroundXSSFColor());
-       assertEquals(0, cs.getFillForegroundColor());
-       assertEquals("FFFF0000", cs.getFillForegroundXSSFColor().getARGBHex());
-       assertEquals("FFFF0000", cs.getFillForegroundColorColor().getARGBHex());
-       
-       assertNotNull(cs.getFillBackgroundColor());
-       assertEquals(64, cs.getFillBackgroundColor());
-       assertEquals(null, cs.getFillBackgroundXSSFColor().getARGBHex());
-       assertEquals(null, cs.getFillBackgroundColorColor().getARGBHex());
+        assertNotNull(cs);
+        assertEquals(1, cs.getIndex());
+
+        // Look at the low level xml elements
+        assertEquals(2, cs.getCoreXf().getFillId());
+        assertEquals(0, cs.getCoreXf().getXfId());
+        assertEquals(true, cs.getCoreXf().getApplyFill());
+
+        XSSFCellFill fg = wb.getStylesSource().getFillAt(2);
+        assertEquals(0, fg.getFillForegroundColor().getIndexed());
+        assertEquals(0.0, fg.getFillForegroundColor().getTint(), 0);
+        assertEquals("FFFF0000", fg.getFillForegroundColor().getARGBHex());
+        assertEquals(64, fg.getFillBackgroundColor().getIndexed());
+
+        // Now look higher up
+        assertNotNull(cs.getFillForegroundXSSFColor());
+        assertEquals(0, cs.getFillForegroundColor());
+        assertEquals("FFFF0000", cs.getFillForegroundXSSFColor().getARGBHex());
+        assertEquals("FFFF0000", cs.getFillForegroundColorColor().getARGBHex());
+
+        assertNotNull(cs.getFillBackgroundColor());
+        assertEquals(64, cs.getFillBackgroundColor());
+        assertEquals(null, cs.getFillBackgroundXSSFColor().getARGBHex());
+        assertEquals(null, cs.getFillBackgroundColorColor().getARGBHex());
     }
-    
-    /**
-     * With HSSF, if you create a font, don't change it, and
-     *  create a 2nd, you really do get two fonts that you 
-     *  can alter as and when you want.
-     * With XSSF, that wasn't the case, but this verfies
-     *  that it now is again
-     */
-    @Test
-    public void bug48718() throws Exception {
-       // Verify the HSSF behaviour
-       // Then ensure the same for XSSF
-       Workbook[] wbs = new Workbook[] {
-             new HSSFWorkbook(),
-             new XSSFWorkbook()
-       };
-       int[] initialFonts = new int[] { 4, 1 };
-       for(int i=0; i<wbs.length; i++) {
-          Workbook wb = wbs[i];
-          int startingFonts = initialFonts[i];
-          
-          assertEquals(startingFonts, wb.getNumberOfFonts());
-          
-          // Get a font, and slightly change it
-          Font a = wb.createFont();
-          assertEquals(startingFonts+1, wb.getNumberOfFonts());
-          a.setFontHeightInPoints((short)23);
-          assertEquals(startingFonts+1, wb.getNumberOfFonts());
-          
-          // Get two more, unchanged
-          /*Font b =*/ wb.createFont();
-          assertEquals(startingFonts+2, wb.getNumberOfFonts());
-          /*Font c =*/ wb.createFont();
-          assertEquals(startingFonts+3, wb.getNumberOfFonts());
-       }
-    }
-    
+
     /**
      * Ensure General and @ format are working properly
      *  for integers 
      */
     @Test
     public void bug47490() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GeneralFormatTests.xlsx");
-       Sheet s = wb.getSheetAt(1);
-       Row r;
-       DataFormatter df = new DataFormatter();
-       
-       r = s.getRow(1);
-       assertEquals(1.0, r.getCell(2).getNumericCellValue(), 0);
-       assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
-       assertEquals("1", df.formatCellValue(r.getCell(2)));
-       assertEquals("1", df.formatRawCellContents(1.0, -1, "@"));
-       assertEquals("1", df.formatRawCellContents(1.0, -1, "General"));
-              
-       r = s.getRow(2);
-       assertEquals(12.0, r.getCell(2).getNumericCellValue(), 0);
-       assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
-       assertEquals("12", df.formatCellValue(r.getCell(2)));
-       assertEquals("12", df.formatRawCellContents(12.0, -1, "@"));
-       assertEquals("12", df.formatRawCellContents(12.0, -1, "General"));
-       
-       r = s.getRow(3);
-       assertEquals(123.0, r.getCell(2).getNumericCellValue(), 0);
-       assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
-       assertEquals("123", df.formatCellValue(r.getCell(2)));
-       assertEquals("123", df.formatRawCellContents(123.0, -1, "@"));
-       assertEquals("123", df.formatRawCellContents(123.0, -1, "General"));
-    }
-    
-    /**
-     * Ensures that XSSF and HSSF agree with each other,
-     *  and with the docs on when fetching the wrong
-     *  kind of value from a Formula cell
-     */
-    @Test
-    public void bug47815() {
-       Workbook[] wbs = new Workbook[] {
-             new HSSFWorkbook(),
-             new XSSFWorkbook()
-       };
-       for(Workbook wb : wbs) {
-          Sheet s = wb.createSheet();
-          Row r = s.createRow(0);
-          
-          // Setup
-          Cell cn = r.createCell(0, Cell.CELL_TYPE_NUMERIC);
-          cn.setCellValue(1.2);
-          Cell cs = r.createCell(1, Cell.CELL_TYPE_STRING);
-          cs.setCellValue("Testing");
-          
-          Cell cfn = r.createCell(2, Cell.CELL_TYPE_FORMULA);
-          cfn.setCellFormula("A1");  
-          Cell cfs = r.createCell(3, Cell.CELL_TYPE_FORMULA);
-          cfs.setCellFormula("B1");
-          
-          FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
-          assertEquals(Cell.CELL_TYPE_NUMERIC, fe.evaluate(cfn).getCellType());
-          assertEquals(Cell.CELL_TYPE_STRING, fe.evaluate(cfs).getCellType());
-          fe.evaluateFormulaCell(cfn);
-          fe.evaluateFormulaCell(cfs);
-          
-          // Now test
-          assertEquals(Cell.CELL_TYPE_NUMERIC, cn.getCellType());
-          assertEquals(Cell.CELL_TYPE_STRING, cs.getCellType());
-          assertEquals(Cell.CELL_TYPE_FORMULA, cfn.getCellType());
-          assertEquals(Cell.CELL_TYPE_NUMERIC, cfn.getCachedFormulaResultType());
-          assertEquals(Cell.CELL_TYPE_FORMULA, cfs.getCellType());
-          assertEquals(Cell.CELL_TYPE_STRING, cfs.getCachedFormulaResultType());
-          
-          // Different ways of retrieving
-          assertEquals(1.2, cn.getNumericCellValue(), 0);
-          try {
-             cn.getRichStringCellValue();
-             fail();
-          } catch(IllegalStateException e) {}
-          
-          assertEquals("Testing", cs.getStringCellValue());
-          try {
-             cs.getNumericCellValue();
-             fail();
-          } catch(IllegalStateException e) {}
-          
-          assertEquals(1.2, cfn.getNumericCellValue(), 0);
-          try {
-             cfn.getRichStringCellValue();
-             fail();
-          } catch(IllegalStateException e) {}
-          
-          assertEquals("Testing", cfs.getStringCellValue());
-          try {
-             cfs.getNumericCellValue();
-             fail();
-          } catch(IllegalStateException e) {}
-       }
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GeneralFormatTests.xlsx");
+        Sheet s = wb.getSheetAt(1);
+        Row r;
+        DataFormatter df = new DataFormatter();
+
+        r = s.getRow(1);
+        assertEquals(1.0, r.getCell(2).getNumericCellValue(), 0);
+        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
+        assertEquals("1", df.formatCellValue(r.getCell(2)));
+        assertEquals("1", df.formatRawCellContents(1.0, -1, "@"));
+        assertEquals("1", df.formatRawCellContents(1.0, -1, "General"));
+
+        r = s.getRow(2);
+        assertEquals(12.0, r.getCell(2).getNumericCellValue(), 0);
+        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
+        assertEquals("12", df.formatCellValue(r.getCell(2)));
+        assertEquals("12", df.formatRawCellContents(12.0, -1, "@"));
+        assertEquals("12", df.formatRawCellContents(12.0, -1, "General"));
+
+        r = s.getRow(3);
+        assertEquals(123.0, r.getCell(2).getNumericCellValue(), 0);
+        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
+        assertEquals("123", df.formatCellValue(r.getCell(2)));
+        assertEquals("123", df.formatRawCellContents(123.0, -1, "@"));
+        assertEquals("123", df.formatRawCellContents(123.0, -1, "General"));
     }
 
     /**
@@ -496,7 +423,7 @@
         assertEquals(Cell.CELL_TYPE_ERROR, evaluator.evaluateInCell(cell).getCellType());
         assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
     }
-    
+
     /**
      * Creating a rich string of "hello world" and applying
      *  a font to characters 1-5 means we have two strings,
@@ -506,101 +433,102 @@
      */
     @Test
     public void bug49941() throws Exception {
-       XSSFWorkbook wb = new XSSFWorkbook();
-       XSSFSheet s = wb.createSheet();
-       XSSFRow r = s.createRow(0);
-       XSSFCell c = r.createCell(0);
-       
-       // First without fonts
-       c.setCellValue(
-             new XSSFRichTextString(" with spaces ")
-       );
-       assertEquals(" with spaces ", c.getRichStringCellValue().toString());
-       assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
-       assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
-       // Should have the preserve set
-       assertEquals(
-             1,
-             c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
-       );
-       assertEquals(
-             "preserve",
-             c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().item(0).getNodeValue()
-       );
-       
-       // Save and check
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       s = wb.getSheetAt(0);
-       r = s.getRow(0);
-       c = r.getCell(0);
-       assertEquals(" with spaces ", c.getRichStringCellValue().toString());
-       assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
-       assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
-       
-       // Change the string
-       c.setCellValue(
-             new XSSFRichTextString("hello world")
-       );
-       assertEquals("hello world", c.getRichStringCellValue().toString());
-       // Won't have preserve
-       assertEquals(
-             0,
-             c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
-       );
-       
-       // Apply a font
-       XSSFFont f = wb.createFont();
-       f.setBold(true);
-       c.getRichStringCellValue().applyFont(0, 5, f);
-       assertEquals("hello world", c.getRichStringCellValue().toString());
-       // Does need preserving on the 2nd part
-       assertEquals(2, c.getRichStringCellValue().getCTRst().sizeOfRArray());
-       assertEquals(
-             0,
-             c.getRichStringCellValue().getCTRst().getRArray(0).xgetT().getDomNode().getAttributes().getLength()
-       );
-       assertEquals(
-             1,
-             c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().getLength()
-       );
-       assertEquals(
-             "preserve",
-             c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().item(0).getNodeValue()
-       );
-       
-       // Save and check
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       s = wb.getSheetAt(0);
-       r = s.getRow(0);
-       c = r.getCell(0);
-       assertEquals("hello world", c.getRichStringCellValue().toString());
-       wb.close();
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet s = wb.createSheet();
+        XSSFRow r = s.createRow(0);
+        XSSFCell c = r.createCell(0);
+
+        // First without fonts
+        c.setCellValue(
+                new XSSFRichTextString(" with spaces ")
+        );
+        assertEquals(" with spaces ", c.getRichStringCellValue().toString());
+        assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
+        assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
+        // Should have the preserve set
+        assertEquals(
+                1,
+                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
+        );
+        assertEquals(
+                "preserve",
+                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().item(0).getNodeValue()
+        );
+
+        // Save and check
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        wb.close();
+        s = wbBack.getSheetAt(0);
+        r = s.getRow(0);
+        c = r.getCell(0);
+        assertEquals(" with spaces ", c.getRichStringCellValue().toString());
+        assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
+        assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
+
+        // Change the string
+        c.setCellValue(
+                new XSSFRichTextString("hello world")
+        );
+        assertEquals("hello world", c.getRichStringCellValue().toString());
+        // Won't have preserve
+        assertEquals(
+                0,
+                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
+        );
+
+        // Apply a font
+        XSSFFont f = wbBack.createFont();
+        f.setBold(true);
+        c.getRichStringCellValue().applyFont(0, 5, f);
+        assertEquals("hello world", c.getRichStringCellValue().toString());
+        // Does need preserving on the 2nd part
+        assertEquals(2, c.getRichStringCellValue().getCTRst().sizeOfRArray());
+        assertEquals(
+                0,
+                c.getRichStringCellValue().getCTRst().getRArray(0).xgetT().getDomNode().getAttributes().getLength()
+        );
+        assertEquals(
+                1,
+                c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().getLength()
+        );
+        assertEquals(
+                "preserve",
+                c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().item(0).getNodeValue()
+        );
+
+        // Save and check
+        wbBack = XSSFTestDataSamples.writeOutAndReadBack(wbBack);
+        s = wbBack.getSheetAt(0);
+        r = s.getRow(0);
+        c = r.getCell(0);
+        assertEquals("hello world", c.getRichStringCellValue().toString());
+        wbBack.close();
     }
-    
+
     /**
      * Repeatedly writing the same file which has styles
      */
     @Test
     public void bug49940() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx");
-       assertEquals(3, wb.getNumberOfSheets());
-       assertEquals(10, wb.getStylesSource().getNumCellStyles());
-       
-       ByteArrayOutputStream b1 = new ByteArrayOutputStream();
-       ByteArrayOutputStream b2 = new ByteArrayOutputStream();
-       ByteArrayOutputStream b3 = new ByteArrayOutputStream();
-       wb.write(b1);
-       wb.write(b2);
-       wb.write(b3);
-       
-       for(byte[] data : new byte[][] {
-             b1.toByteArray(), b2.toByteArray(), b3.toByteArray()
-       }) {
-          ByteArrayInputStream bais = new ByteArrayInputStream(data);
-          wb = new XSSFWorkbook(bais);
-          assertEquals(3, wb.getNumberOfSheets());
-          assertEquals(10, wb.getStylesSource().getNumCellStyles());
-       }
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx");
+        assertEquals(3, wb.getNumberOfSheets());
+        assertEquals(10, wb.getStylesSource().getNumCellStyles());
+
+        ByteArrayOutputStream b1 = new ByteArrayOutputStream();
+        ByteArrayOutputStream b2 = new ByteArrayOutputStream();
+        ByteArrayOutputStream b3 = new ByteArrayOutputStream();
+        wb.write(b1);
+        wb.write(b2);
+        wb.write(b3);
+
+        for(byte[] data : new byte[][] {
+                b1.toByteArray(), b2.toByteArray(), b3.toByteArray()
+        }) {
+            ByteArrayInputStream bais = new ByteArrayInputStream(data);
+            wb = new XSSFWorkbook(bais);
+            assertEquals(3, wb.getNumberOfSheets());
+            assertEquals(10, wb.getStylesSource().getNumCellStyles());
+        }
     }
 
     /**
@@ -626,7 +554,7 @@
         assertEquals("A8", cc.getCTCalcChain().getCArray(6).getR());
         assertEquals(40, cc.getCTCalcChain().sizeOfCArray());
         wbRead.close();
-        
+
         wbRead = XSSFTestDataSamples.writeOutAndReadBack(wb);
 
         // Try various ways of changing the formulas
@@ -646,7 +574,7 @@
         validateCells(sheet);
         wbRead.close();
         wbRead = XSSFTestDataSamples.writeOutAndReadBack(wb);
-        
+
         sheet.getRow(6).getCell(0).setCellType(Cell.CELL_TYPE_BLANK); // go
         wbRead.close();
         wbRead = XSSFTestDataSamples.writeOutAndReadBack(wb);
@@ -698,85 +626,85 @@
             }
         }
     }
-    
+
     /**
      * Newlines are valid characters in a formula
      */
     @Test
     public void bug50440And51875() throws Exception {
-       Workbook wb = XSSFTestDataSamples.openSampleWorkbook("NewlineInFormulas.xlsx");
-       Sheet s = wb.getSheetAt(0);
-       Cell c = s.getRow(0).getCell(0);
-       
-       assertEquals("SUM(\n1,2\n)", c.getCellFormula());
-       assertEquals(3.0, c.getNumericCellValue(), 0);
-       
-       FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
-       formulaEvaluator.evaluateFormulaCell(c);
-       
-       assertEquals("SUM(\n1,2\n)", c.getCellFormula());
-       assertEquals(3.0, c.getNumericCellValue(), 0);
+        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("NewlineInFormulas.xlsx");
+        Sheet s = wb.getSheetAt(0);
+        Cell c = s.getRow(0).getCell(0);
 
-       // For 51875
-       Cell b3 = s.getRow(2).getCell(1);
-       formulaEvaluator.evaluateFormulaCell(b3);
-       assertEquals("B1+B2", b3.getCellFormula()); // The newline is lost for shared formulas
-       assertEquals(3.0, b3.getNumericCellValue(), 0);
+        assertEquals("SUM(\n1,2\n)", c.getCellFormula());
+        assertEquals(3.0, c.getNumericCellValue(), 0);
+
+        FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+        formulaEvaluator.evaluateFormulaCell(c);
+
+        assertEquals("SUM(\n1,2\n)", c.getCellFormula());
+        assertEquals(3.0, c.getNumericCellValue(), 0);
+
+        // For 51875
+        Cell b3 = s.getRow(2).getCell(1);
+        formulaEvaluator.evaluateFormulaCell(b3);
+        assertEquals("B1+B2", b3.getCellFormula()); // The newline is lost for shared formulas
+        assertEquals(3.0, b3.getNumericCellValue(), 0);
     }
-    
+
     /**
      * Moving a cell comment from one cell to another
      */
     @Test
     public void bug50795() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50795.xlsx");
-       XSSFSheet sheet = wb.getSheetAt(0);
-       XSSFRow row = sheet.getRow(0);
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50795.xlsx");
+        XSSFSheet sheet = wb.getSheetAt(0);
+        XSSFRow row = sheet.getRow(0);
 
-       XSSFCell cellWith = row.getCell(0);
-       XSSFCell cellWithoutComment = row.getCell(1);
-       
-       assertNotNull(cellWith.getCellComment());
-       assertNull(cellWithoutComment.getCellComment());
-       
-       String exp = "\u0410\u0432\u0442\u043e\u0440:\ncomment";
-       XSSFComment comment = cellWith.getCellComment();
-       assertEquals(exp, comment.getString().getString());
-       
-       
-       // Check we can write it out and read it back as-is
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       sheet = wb.getSheetAt(0);
-       row = sheet.getRow(0);
-       cellWith = row.getCell(0);
-       cellWithoutComment = row.getCell(1);
-       
-       // Double check things are as expected
-       assertNotNull(cellWith.getCellComment());
-       assertNull(cellWithoutComment.getCellComment());
-       comment = cellWith.getCellComment();
-       assertEquals(exp, comment.getString().getString());
+        XSSFCell cellWith = row.getCell(0);
+        XSSFCell cellWithoutComment = row.getCell(1);
 
-       
-       // Move the comment
-       cellWithoutComment.setCellComment(comment);
-       
-       
-       // Write out and re-check
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       sheet = wb.getSheetAt(0);
-       row = sheet.getRow(0);
-       
-       // Ensure it swapped over
-       cellWith = row.getCell(0);
-       cellWithoutComment = row.getCell(1);
-       assertNull(cellWith.getCellComment());
-       assertNotNull(cellWithoutComment.getCellComment());
-       
-       comment = cellWithoutComment.getCellComment();
-       assertEquals(exp, comment.getString().getString());
+        assertNotNull(cellWith.getCellComment());
+        assertNull(cellWithoutComment.getCellComment());
+
+        String exp = "\u0410\u0432\u0442\u043e\u0440:\ncomment";
+        XSSFComment comment = cellWith.getCellComment();
+        assertEquals(exp, comment.getString().getString());
+
+
+        // Check we can write it out and read it back as-is
+        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        row = sheet.getRow(0);
+        cellWith = row.getCell(0);
+        cellWithoutComment = row.getCell(1);
+
+        // Double check things are as expected
+        assertNotNull(cellWith.getCellComment());
+        assertNull(cellWithoutComment.getCellComment());
+        comment = cellWith.getCellComment();
+        assertEquals(exp, comment.getString().getString());
+
+
+        // Move the comment
+        cellWithoutComment.setCellComment(comment);
+
+
+        // Write out and re-check
+        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        row = sheet.getRow(0);
+
+        // Ensure it swapped over
+        cellWith = row.getCell(0);
+        cellWithoutComment = row.getCell(1);
+        assertNull(cellWith.getCellComment());
+        assertNotNull(cellWithoutComment.getCellComment());
+
+        comment = cellWithoutComment.getCellComment();
+        assertEquals(exp, comment.getString().getString());
     }
-    
+
     /**
      * When the cell background colour is set with one of the first
      *  two columns of the theme colour palette, the colours are 
@@ -785,80 +713,80 @@
      */
     @Test
     public void bug50299() throws Exception {
-       Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
-       
-       // Check all the colours
-       for(int sn=0; sn<wb.getNumberOfSheets(); sn++) {
-          Sheet s = wb.getSheetAt(sn);
-          for(Row r : s) {
-             for(Cell c : r) {
-                CellStyle cs = c.getCellStyle();
-                if(cs != null) {
-                   cs.getFillForegroundColor();
+        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
+
+        // Check all the colours
+        for(int sn=0; sn<wb.getNumberOfSheets(); sn++) {
+            Sheet s = wb.getSheetAt(sn);
+            for(Row r : s) {
+                for(Cell c : r) {
+                    CellStyle cs = c.getCellStyle();
+                    if(cs != null) {
+                        cs.getFillForegroundColor();
+                    }
                 }
-             }
-          }
-       }
-       
-       // Check one bit in detail
-       // Check that we get back foreground=0 for the theme colours,
-       //  and background=64 for the auto colouring
-       Sheet s = wb.getSheetAt(0);
-       assertEquals(0,  s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
-       assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
-       assertEquals(0,  s.getRow(1).getCell(8).getCellStyle().getFillForegroundColor());
-       assertEquals(64, s.getRow(1).getCell(8).getCellStyle().getFillBackgroundColor());
+            }
+        }
+
+        // Check one bit in detail
+        // Check that we get back foreground=0 for the theme colours,
+        //  and background=64 for the auto colouring
+        Sheet s = wb.getSheetAt(0);
+        assertEquals(0,  s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
+        assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
+        assertEquals(0,  s.getRow(1).getCell(8).getCellStyle().getFillForegroundColor());
+        assertEquals(64, s.getRow(1).getCell(8).getCellStyle().getFillBackgroundColor());
     }
-    
+
     /**
      * Excel .xls style indexed colours in a .xlsx file
      */
     @Test
     public void bug50786() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50786-indexed_colours.xlsx");
-       XSSFSheet s = wb.getSheetAt(0);
-       XSSFRow r = s.getRow(2);
-       
-       // Check we have the right cell
-       XSSFCell c = r.getCell(1);
-       assertEquals("test\u00a0", c.getRichStringCellValue().getString());
-       
-       // It should be light green
-       XSSFCellStyle cs = c.getCellStyle();
-       assertEquals(42, cs.getFillForegroundColor());
-       assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
-       assertNotNull(cs.getFillForegroundColorColor().getRgb());
-       assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50786-indexed_colours.xlsx");
+        XSSFSheet s = wb.getSheetAt(0);
+        XSSFRow r = s.getRow(2);
+
+        // Check we have the right cell
+        XSSFCell c = r.getCell(1);
+        assertEquals("test\u00a0", c.getRichStringCellValue().getString());
+
+        // It should be light green
+        XSSFCellStyle cs = c.getCellStyle();
+        assertEquals(42, cs.getFillForegroundColor());
+        assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
+        assertNotNull(cs.getFillForegroundColorColor().getRgb());
+        assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
     }
-    
+
     /**
      * If the border colours are set with themes, then we 
      *  should still be able to get colours
      */
     @Test
     public void bug50846() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50846-border_colours.xlsx");
-       
-       XSSFSheet sheet = wb.getSheetAt(0);
-       XSSFRow row = sheet.getRow(0);
-       
-       // Border from a theme, brown
-       XSSFCell cellT = row.getCell(0);
-       XSSFCellStyle styleT = cellT.getCellStyle();
-       XSSFColor colorT = styleT.getBottomBorderXSSFColor();
-       
-       assertEquals(5, colorT.getTheme());
-       assertEquals("FFC0504D", colorT.getARGBHex());
-       
-       // Border from a style direct, red
-       XSSFCell cellS = row.getCell(1);
-       XSSFCellStyle styleS = cellS.getCellStyle();
-       XSSFColor colorS = styleS.getBottomBorderXSSFColor();
-       
-       assertEquals(0, colorS.getTheme());
-       assertEquals("FFFF0000", colorS.getARGBHex());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50846-border_colours.xlsx");
+
+        XSSFSheet sheet = wb.getSheetAt(0);
+        XSSFRow row = sheet.getRow(0);
+
+        // Border from a theme, brown
+        XSSFCell cellT = row.getCell(0);
+        XSSFCellStyle styleT = cellT.getCellStyle();
+        XSSFColor colorT = styleT.getBottomBorderXSSFColor();
+
+        assertEquals(5, colorT.getTheme());
+        assertEquals("FFC0504D", colorT.getARGBHex());
+
+        // Border from a style direct, red
+        XSSFCell cellS = row.getCell(1);
+        XSSFCellStyle styleS = cellS.getCellStyle();
+        XSSFColor colorS = styleS.getBottomBorderXSSFColor();
+
+        assertEquals(0, colorS.getTheme());
+        assertEquals("FFFF0000", colorS.getARGBHex());
     }
-    
+
     /**
      * Fonts where their colours come from the theme rather
      *  then being set explicitly still should allow the
@@ -866,28 +794,28 @@
      */
     @Test
     public void bug50784() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50784-font_theme_colours.xlsx");
-       XSSFSheet s = wb.getSheetAt(0);
-       XSSFRow r = s.getRow(0);
-       
-       // Column 1 has a font with regular colours
-       XSSFCell cr = r.getCell(1);
-       XSSFFont fr = wb.getFontAt( cr.getCellStyle().getFontIndex() );
-       XSSFColor colr =  fr.getXSSFColor();
-       // No theme, has colours
-       assertEquals(0, colr.getTheme());
-       assertNotNull( colr.getRgb() );
-       
-       // Column 0 has a font with colours from a theme
-       XSSFCell ct = r.getCell(0);
-       XSSFFont ft = wb.getFontAt( ct.getCellStyle().getFontIndex() );
-       XSSFColor colt =  ft.getXSSFColor();
-       // Has a theme, which has the colours on it
-       assertEquals(9, colt.getTheme());
-       XSSFColor themeC = wb.getTheme().getThemeColor(colt.getTheme());
-       assertNotNull( themeC.getRgb() );
-       assertNotNull( colt.getRgb() );
-       assertEquals( themeC.getARGBHex(), colt.getARGBHex() ); // The same colour
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50784-font_theme_colours.xlsx");
+        XSSFSheet s = wb.getSheetAt(0);
+        XSSFRow r = s.getRow(0);
+
+        // Column 1 has a font with regular colours
+        XSSFCell cr = r.getCell(1);
+        XSSFFont fr = wb.getFontAt( cr.getCellStyle().getFontIndex() );
+        XSSFColor colr =  fr.getXSSFColor();
+        // No theme, has colours
+        assertEquals(0, colr.getTheme());
+        assertNotNull( colr.getRgb() );
+
+        // Column 0 has a font with colours from a theme
+        XSSFCell ct = r.getCell(0);
+        XSSFFont ft = wb.getFontAt( ct.getCellStyle().getFontIndex() );
+        XSSFColor colt =  ft.getXSSFColor();
+        // Has a theme, which has the colours on it
+        assertEquals(9, colt.getTheme());
+        XSSFColor themeC = wb.getTheme().getThemeColor(colt.getTheme());
+        assertNotNull( themeC.getRgb() );
+        assertNotNull( colt.getRgb() );
+        assertEquals( themeC.getARGBHex(), colt.getARGBHex() ); // The same colour
     }
 
     /**
@@ -896,232 +824,233 @@
      */
     @Test
     public void bug48877() throws Exception {
-       String text = "Use \n with word wrap on to create a new line.\n" +
-          "This line finishes with two trailing spaces.  ";
-       
-       XSSFWorkbook wb = new XSSFWorkbook();
-       XSSFSheet sheet = wb.createSheet();
+        String text = "Use \n with word wrap on to create a new line.\n" +
+                "This line finishes with two trailing spaces.  ";
 
-       Font font1 = wb.createFont();
-       font1.setColor((short) 20);
-       Font font2 = wb.createFont();
-       font2.setColor(Font.COLOR_RED);
-       Font font3 = wb.getFontAt((short)0);
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet sheet = wb.createSheet();
 
-       XSSFRow row = sheet.createRow(2);
-       XSSFCell cell = row.createCell(2);
+        Font font1 = wb.createFont();
+        font1.setColor((short) 20);
+        Font font2 = wb.createFont();
+        font2.setColor(Font.COLOR_RED);
+        Font font3 = wb.getFontAt((short)0);
 
-       XSSFRichTextString richTextString =
-          wb.getCreationHelper().createRichTextString(text);
-       
-       // Check the text has the newline
-       assertEquals(text, richTextString.getString());
-       
-       // Apply the font
-       richTextString.applyFont(font3);
-       richTextString.applyFont(0, 3, font1);
-       cell.setCellValue(richTextString);
+        XSSFRow row = sheet.createRow(2);
+        XSSFCell cell = row.createCell(2);
 
-       // To enable newlines you need set a cell styles with wrap=true
-       CellStyle cs = wb.createCellStyle();
-       cs.setWrapText(true);
-       cell.setCellStyle(cs);
+        XSSFRichTextString richTextString =
+                wb.getCreationHelper().createRichTextString(text);
 
-       // Check the text has the
-       assertEquals(text, cell.getStringCellValue());
-       
-       // Save the file and re-read it
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       sheet = wb.getSheetAt(0);
-       row = sheet.getRow(2);
-       cell = row.getCell(2);
-       assertEquals(text, cell.getStringCellValue());
-       
-       // Now add a 2nd, and check again
-       int fontAt = text.indexOf("\n", 6);
-       cell.getRichStringCellValue().applyFont(10, fontAt+1, font2);
-       assertEquals(text, cell.getStringCellValue());
-       
-       assertEquals(4, cell.getRichStringCellValue().numFormattingRuns());
-       assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRArray(0).getT());
-       
-       String r3 = cell.getRichStringCellValue().getCTRst().getRArray(2).getT();
-       assertEquals("line.\n", r3.substring(r3.length()-6));
+        // Check the text has the newline
+        assertEquals(text, richTextString.getString());
 
-       // Save and re-check
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       sheet = wb.getSheetAt(0);
-       row = sheet.getRow(2);
-       cell = row.getCell(2);
-       assertEquals(text, cell.getStringCellValue());
-       wb.close();
+        // Apply the font
+        richTextString.applyFont(font3);
+        richTextString.applyFont(0, 3, font1);
+        cell.setCellValue(richTextString);
 
-//       FileOutputStream out = new FileOutputStream("/tmp/test48877.xlsx");
-//       wb.write(out);
-//       out.close();
+        // To enable newlines you need set a cell styles with wrap=true
+        CellStyle cs = wb.createCellStyle();
+        cs.setWrapText(true);
+        cell.setCellStyle(cs);
+
+        // Check the text has the
+        assertEquals(text, cell.getStringCellValue());
+
+        // Save the file and re-read it
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        wb.close();
+        sheet = wbBack.getSheetAt(0);
+        row = sheet.getRow(2);
+        cell = row.getCell(2);
+        assertEquals(text, cell.getStringCellValue());
+
+        // Now add a 2nd, and check again
+        int fontAt = text.indexOf("\n", 6);
+        cell.getRichStringCellValue().applyFont(10, fontAt+1, font2);
+        assertEquals(text, cell.getStringCellValue());
+
+        assertEquals(4, cell.getRichStringCellValue().numFormattingRuns());
+        assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRArray(0).getT());
+
+        String r3 = cell.getRichStringCellValue().getCTRst().getRArray(2).getT();
+        assertEquals("line.\n", r3.substring(r3.length()-6));
+
+        // Save and re-check
+        wbBack = XSSFTestDataSamples.writeOutAndReadBack(wbBack);
+        sheet = wbBack.getSheetAt(0);
+        row = sheet.getRow(2);
+        cell = row.getCell(2);
+        assertEquals(text, cell.getStringCellValue());
+        wbBack.close();
+        
+        // FileOutputStream out = new FileOutputStream("/tmp/test48877.xlsx");
+        // wb.write(out);
+        // out.close();
     }
-    
+
     /**
      * Adding sheets when one has a table, then re-ordering
      */
     @Test
     public void bug50867() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50867_with_table.xlsx");
-       assertEquals(3, wb.getNumberOfSheets());
-       
-       XSSFSheet s1 = wb.getSheetAt(0);
-       XSSFSheet s2 = wb.getSheetAt(1);
-       XSSFSheet s3 = wb.getSheetAt(2);
-       assertEquals(1, s1.getTables().size());
-       assertEquals(0, s2.getTables().size());
-       assertEquals(0, s3.getTables().size());
-       
-       XSSFTable t = s1.getTables().get(0);
-       assertEquals("Tabella1", t.getName());
-       assertEquals("Tabella1", t.getDisplayName());
-       assertEquals("A1:C3", t.getCTTable().getRef());
-       
-       // Add a sheet and re-order
-       XSSFSheet s4 = wb.createSheet("NewSheet");
-       wb.setSheetOrder(s4.getSheetName(), 0);
-       
-       // Check on tables
-       assertEquals(1, s1.getTables().size());
-       assertEquals(0, s2.getTables().size());
-       assertEquals(0, s3.getTables().size());
-       assertEquals(0, s4.getTables().size());
-       
-       // Refetch to get the new order
-       s1 = wb.getSheetAt(0);
-       s2 = wb.getSheetAt(1);
-       s3 = wb.getSheetAt(2);
-       s4 = wb.getSheetAt(3);
-       assertEquals(0, s1.getTables().size());
-       assertEquals(1, s2.getTables().size());
-       assertEquals(0, s3.getTables().size());
-       assertEquals(0, s4.getTables().size());
-       
-       // Save and re-load
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       s1 = wb.getSheetAt(0);
-       s2 = wb.getSheetAt(1);
-       s3 = wb.getSheetAt(2);
-       s4 = wb.getSheetAt(3);
-       assertEquals(0, s1.getTables().size());
-       assertEquals(1, s2.getTables().size());
-       assertEquals(0, s3.getTables().size());
-       assertEquals(0, s4.getTables().size());
-       
-       t = s2.getTables().get(0);
-       assertEquals("Tabella1", t.getName());
-       assertEquals("Tabella1", t.getDisplayName());
-       assertEquals("A1:C3", t.getCTTable().getRef());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50867_with_table.xlsx");
+        assertEquals(3, wb.getNumberOfSheets());
 
-       
-       // Add some more tables, and check
-       t = s2.createTable();
-       t.setName("New 2");
-       t.setDisplayName("New 2");
-       t = s3.createTable();
-       t.setName("New 3");
-       t.setDisplayName("New 3");
-       
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       s1 = wb.getSheetAt(0);
-       s2 = wb.getSheetAt(1);
-       s3 = wb.getSheetAt(2);
-       s4 = wb.getSheetAt(3);
-       assertEquals(0, s1.getTables().size());
-       assertEquals(2, s2.getTables().size());
-       assertEquals(1, s3.getTables().size());
-       assertEquals(0, s4.getTables().size());
-       
-       t = s2.getTables().get(0);
-       assertEquals("Tabella1", t.getName());
-       assertEquals("Tabella1", t.getDisplayName());
-       assertEquals("A1:C3", t.getCTTable().getRef());
-       
-       t = s2.getTables().get(1);
-       assertEquals("New 2", t.getName());
-       assertEquals("New 2", t.getDisplayName());
-       
-       t = s3.getTables().get(0);
-       assertEquals("New 3", t.getName());
-       assertEquals("New 3", t.getDisplayName());
-       
-       // Check the relationships
-       assertEquals(0, s1.getRelations().size());
-       assertEquals(3, s2.getRelations().size());
-       assertEquals(1, s3.getRelations().size());
-       assertEquals(0, s4.getRelations().size());
-       
-       assertEquals(
-             XSSFRelation.PRINTER_SETTINGS.getContentType(), 
-             s2.getRelations().get(0).getPackagePart().getContentType()
-       );
-       assertEquals(
-             XSSFRelation.TABLE.getContentType(), 
-             s2.getRelations().get(1).getPackagePart().getContentType()
-       );
-       assertEquals(
-             XSSFRelation.TABLE.getContentType(), 
-             s2.getRelations().get(2).getPackagePart().getContentType()
-       );
-       assertEquals(
-             XSSFRelation.TABLE.getContentType(), 
-             s3.getRelations().get(0).getPackagePart().getContentType()
-       );
-       assertEquals(
-             "/xl/tables/table3.xml",
-             s3.getRelations().get(0).getPackagePart().getPartName().toString()
-       );
+        XSSFSheet s1 = wb.getSheetAt(0);
+        XSSFSheet s2 = wb.getSheetAt(1);
+        XSSFSheet s3 = wb.getSheetAt(2);
+        assertEquals(1, s1.getTables().size());
+        assertEquals(0, s2.getTables().size());
+        assertEquals(0, s3.getTables().size());
+
+        XSSFTable t = s1.getTables().get(0);
+        assertEquals("Tabella1", t.getName());
+        assertEquals("Tabella1", t.getDisplayName());
+        assertEquals("A1:C3", t.getCTTable().getRef());
+
+        // Add a sheet and re-order
+        XSSFSheet s4 = wb.createSheet("NewSheet");
+        wb.setSheetOrder(s4.getSheetName(), 0);
+
+        // Check on tables
+        assertEquals(1, s1.getTables().size());
+        assertEquals(0, s2.getTables().size());
+        assertEquals(0, s3.getTables().size());
+        assertEquals(0, s4.getTables().size());
+
+        // Refetch to get the new order
+        s1 = wb.getSheetAt(0);
+        s2 = wb.getSheetAt(1);
+        s3 = wb.getSheetAt(2);
+        s4 = wb.getSheetAt(3);
+        assertEquals(0, s1.getTables().size());
+        assertEquals(1, s2.getTables().size());
+        assertEquals(0, s3.getTables().size());
+        assertEquals(0, s4.getTables().size());
+
+        // Save and re-load
+        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        s1 = wb.getSheetAt(0);
+        s2 = wb.getSheetAt(1);
+        s3 = wb.getSheetAt(2);
+        s4 = wb.getSheetAt(3);
+        assertEquals(0, s1.getTables().size());
+        assertEquals(1, s2.getTables().size());
+        assertEquals(0, s3.getTables().size());
+        assertEquals(0, s4.getTables().size());
+
+        t = s2.getTables().get(0);
+        assertEquals("Tabella1", t.getName());
+        assertEquals("Tabella1", t.getDisplayName());
+        assertEquals("A1:C3", t.getCTTable().getRef());
+
+
+        // Add some more tables, and check
+        t = s2.createTable();
+        t.setName("New 2");
+        t.setDisplayName("New 2");
+        t = s3.createTable();
+        t.setName("New 3");
+        t.setDisplayName("New 3");
+
+        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        s1 = wb.getSheetAt(0);
+        s2 = wb.getSheetAt(1);
+        s3 = wb.getSheetAt(2);
+        s4 = wb.getSheetAt(3);
+        assertEquals(0, s1.getTables().size());
+        assertEquals(2, s2.getTables().size());
+        assertEquals(1, s3.getTables().size());
+        assertEquals(0, s4.getTables().size());
+
+        t = s2.getTables().get(0);
+        assertEquals("Tabella1", t.getName());
+        assertEquals("Tabella1", t.getDisplayName());
+        assertEquals("A1:C3", t.getCTTable().getRef());
+
+        t = s2.getTables().get(1);
+        assertEquals("New 2", t.getName());
+        assertEquals("New 2", t.getDisplayName());
+
+        t = s3.getTables().get(0);
+        assertEquals("New 3", t.getName());
+        assertEquals("New 3", t.getDisplayName());
+
+        // Check the relationships
+        assertEquals(0, s1.getRelations().size());
+        assertEquals(3, s2.getRelations().size());
+        assertEquals(1, s3.getRelations().size());
+        assertEquals(0, s4.getRelations().size());
+
+        assertEquals(
+                XSSFRelation.PRINTER_SETTINGS.getContentType(), 
+                s2.getRelations().get(0).getPackagePart().getContentType()
+        );
+        assertEquals(
+                XSSFRelation.TABLE.getContentType(), 
+                s2.getRelations().get(1).getPackagePart().getContentType()
+        );
+        assertEquals(
+                XSSFRelation.TABLE.getContentType(), 
+                s2.getRelations().get(2).getPackagePart().getContentType()
+        );
+        assertEquals(
+                XSSFRelation.TABLE.getContentType(), 
+                s3.getRelations().get(0).getPackagePart().getContentType()
+        );
+        assertEquals(
+                "/xl/tables/table3.xml",
+                s3.getRelations().get(0).getPackagePart().getPartName().toString()
+        );
     }
-    
+
     /**
      * Setting repeating rows and columns shouldn't break
      *  any print settings that were there before
      */
     @SuppressWarnings("deprecation")
     @Test
-	public void bug49253() throws Exception {
-       XSSFWorkbook wb1 = new XSSFWorkbook();
-       XSSFWorkbook wb2 = new XSSFWorkbook();
-       
-       // No print settings before repeating
-       XSSFSheet s1 = wb1.createSheet(); 
-       assertEquals(false, s1.getCTWorksheet().isSetPageSetup());
-       assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
-       
-       wb1.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);
-       
-       assertEquals(true, s1.getCTWorksheet().isSetPageSetup());
-       assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
-       
-       XSSFPrintSetup ps1 = s1.getPrintSetup();
-       assertEquals(false, ps1.getValidSettings());
-       assertEquals(false, ps1.getLandscape());
-       
-       
-       // Had valid print settings before repeating
-       XSSFSheet s2 = wb2.createSheet();
-       XSSFPrintSetup ps2 = s2.getPrintSetup();
-       assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
-       assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
-       
-       ps2.setLandscape(false);
-       assertEquals(true, ps2.getValidSettings());
-       assertEquals(false, ps2.getLandscape());
-       
-       wb2.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);
-       
-       ps2 = s2.getPrintSetup();
-       assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
-       assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
-       assertEquals(true, ps2.getValidSettings());
-       assertEquals(false, ps2.getLandscape());
-       
-       wb1.close();
-       wb2.close();
+    public void bug49253() throws Exception {
+        XSSFWorkbook wb1 = new XSSFWorkbook();
+        XSSFWorkbook wb2 = new XSSFWorkbook();
+
+        // No print settings before repeating
+        XSSFSheet s1 = wb1.createSheet(); 
+        assertEquals(false, s1.getCTWorksheet().isSetPageSetup());
+        assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
+
+        wb1.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);
+
+        assertEquals(true, s1.getCTWorksheet().isSetPageSetup());
+        assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
+
+        PrintSetup ps1 = s1.getPrintSetup();
+        assertEquals(false, ps1.getValidSettings());
+        assertEquals(false, ps1.getLandscape());
+
+
+        // Had valid print settings before repeating
+        XSSFSheet s2 = wb2.createSheet();
+        PrintSetup ps2 = s2.getPrintSetup();
+        assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
+        assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
+
+        ps2.setLandscape(false);
+        assertEquals(true, ps2.getValidSettings());
+        assertEquals(false, ps2.getLandscape());
+
+        wb2.setRepeatingRowsAndColumns(0, 2, 3, 1, 2);
+
+        ps2 = s2.getPrintSetup();
+        assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
+        assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
+        assertEquals(true, ps2.getValidSettings());
+        assertEquals(false, ps2.getLandscape());
+
+        wb1.close();
+        wb2.close();
     }
 
     /**
@@ -1129,140 +1058,141 @@
      */
     @Test
     public void bug51037() throws Exception {
-       XSSFWorkbook wb = new XSSFWorkbook();
-       XSSFSheet s = wb.createSheet();
-       
-       CellStyle defaultStyle = wb.getCellStyleAt((short)0);
-       assertEquals(0, defaultStyle.getIndex());
-       
-       CellStyle blueStyle = wb.createCellStyle();
-       blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
-       blueStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
-       assertEquals(1, blueStyle.getIndex());
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet s = wb.createSheet();
 
-       CellStyle pinkStyle = wb.createCellStyle();
-       pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
-       pinkStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
-       assertEquals(2, pinkStyle.getIndex());
+        CellStyle defaultStyle = wb.getCellStyleAt((short)0);
+        assertEquals(0, defaultStyle.getIndex());
 
-       // Starts empty
-       assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
-       CTCols cols = s.getCTWorksheet().getColsArray(0);
-       assertEquals(0, cols.sizeOfColArray());
-       
-       // Add some rows and columns
-       XSSFRow r1 = s.createRow(0);
-       XSSFRow r2 = s.createRow(1);
-       r1.createCell(0);
-       r1.createCell(2);
-       r2.createCell(0);
-       r2.createCell(3);
-       
-       // Check no style is there
-       assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
-       assertEquals(0, cols.sizeOfColArray());
-       
-       assertEquals(defaultStyle, s.getColumnStyle(0));
-       assertEquals(defaultStyle, s.getColumnStyle(2));
-       assertEquals(defaultStyle, s.getColumnStyle(3));
-       
-       
-       // Apply the styles
-       s.setDefaultColumnStyle(0, pinkStyle);
-       s.setDefaultColumnStyle(3, blueStyle);
-       
-       // Check
-       assertEquals(pinkStyle, s.getColumnStyle(0));
-       assertEquals(defaultStyle, s.getColumnStyle(2));
-       assertEquals(blueStyle, s.getColumnStyle(3));
-       
-       assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
-       assertEquals(2, cols.sizeOfColArray());
-       
-       assertEquals(1, cols.getColArray(0).getMin());
-       assertEquals(1, cols.getColArray(0).getMax());
-       assertEquals(pinkStyle.getIndex(), cols.getColArray(0).getStyle());
-       
-       assertEquals(4, cols.getColArray(1).getMin());
-       assertEquals(4, cols.getColArray(1).getMax());
-       assertEquals(blueStyle.getIndex(), cols.getColArray(1).getStyle());
-       
-       
-       // Save, re-load and re-check 
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       s = wb.getSheetAt(0);
-       defaultStyle = wb.getCellStyleAt(defaultStyle.getIndex());
-       blueStyle = wb.getCellStyleAt(blueStyle.getIndex());
-       pinkStyle = wb.getCellStyleAt(pinkStyle.getIndex());
-       
-       assertEquals(pinkStyle, s.getColumnStyle(0));
-       assertEquals(defaultStyle, s.getColumnStyle(2));
-       assertEquals(blueStyle, s.getColumnStyle(3));
-       wb.close();
+        CellStyle blueStyle = wb.createCellStyle();
+        blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
+        blueStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
+        assertEquals(1, blueStyle.getIndex());
+
+        CellStyle pinkStyle = wb.createCellStyle();
+        pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
+        pinkStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
+        assertEquals(2, pinkStyle.getIndex());
+
+        // Starts empty
+        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
+        CTCols cols = s.getCTWorksheet().getColsArray(0);
+        assertEquals(0, cols.sizeOfColArray());
+
+        // Add some rows and columns
+        XSSFRow r1 = s.createRow(0);
+        XSSFRow r2 = s.createRow(1);
+        r1.createCell(0);
+        r1.createCell(2);
+        r2.createCell(0);
+        r2.createCell(3);
+
+        // Check no style is there
+        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
+        assertEquals(0, cols.sizeOfColArray());
+
+        assertEquals(defaultStyle, s.getColumnStyle(0));
+        assertEquals(defaultStyle, s.getColumnStyle(2));
+        assertEquals(defaultStyle, s.getColumnStyle(3));
+
+
+        // Apply the styles
+        s.setDefaultColumnStyle(0, pinkStyle);
+        s.setDefaultColumnStyle(3, blueStyle);
+
+        // Check
+        assertEquals(pinkStyle, s.getColumnStyle(0));
+        assertEquals(defaultStyle, s.getColumnStyle(2));
+        assertEquals(blueStyle, s.getColumnStyle(3));
+
+        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
+        assertEquals(2, cols.sizeOfColArray());
+
+        assertEquals(1, cols.getColArray(0).getMin());
+        assertEquals(1, cols.getColArray(0).getMax());
+        assertEquals(pinkStyle.getIndex(), cols.getColArray(0).getStyle());
+
+        assertEquals(4, cols.getColArray(1).getMin());
+        assertEquals(4, cols.getColArray(1).getMax());
+        assertEquals(blueStyle.getIndex(), cols.getColArray(1).getStyle());
+
+
+        // Save, re-load and re-check 
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        wb.close();
+        s = wbBack.getSheetAt(0);
+        defaultStyle = wbBack.getCellStyleAt(defaultStyle.getIndex());
+        blueStyle = wbBack.getCellStyleAt(blueStyle.getIndex());
+        pinkStyle = wbBack.getCellStyleAt(pinkStyle.getIndex());
+
+        assertEquals(pinkStyle, s.getColumnStyle(0));
+        assertEquals(defaultStyle, s.getColumnStyle(2));
+        assertEquals(blueStyle, s.getColumnStyle(3));
+        wbBack.close();
     }
-    
+
     /**
      * Repeatedly writing a file.
      * Something with the SharedStringsTable currently breaks...
      */
     @Test
     public void bug46662() throws Exception {
-       // New file
-       XSSFWorkbook wb = new XSSFWorkbook();
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       
-       // Simple file
-       wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       XSSFTestDataSamples.writeOutAndReadBack(wb);
-       
-       // Complex file
-       // TODO
+        // New file
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+
+        // Simple file
+        wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+        XSSFTestDataSamples.writeOutAndReadBack(wb);
+
+        // Complex file
+        // TODO
     }
-    
+
     /**
      * Colours and styles when the list has gaps in it 
      */
     @Test
     public void bug51222() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51222.xlsx");
-       XSSFSheet s = wb.getSheetAt(0);
-       
-       XSSFCell cA4_EEECE1 = s.getRow(3).getCell(0);
-       XSSFCell cA5_1F497D = s.getRow(4).getCell(0);
-       
-       // Check the text
-       assertEquals("A4", cA4_EEECE1.getRichStringCellValue().getString());
-       assertEquals("A5", cA5_1F497D.getRichStringCellValue().getString());
-       
-       // Check the styles assigned to them
-       assertEquals(4, cA4_EEECE1.getCTCell().getS());
-       assertEquals(5, cA5_1F497D.getCTCell().getS());
-       
-       // Check we look up the correct style
-       assertEquals(4, cA4_EEECE1.getCellStyle().getIndex());
-       assertEquals(5, cA5_1F497D.getCellStyle().getIndex());
-       
-       // Check the fills on them at the low level
-       assertEquals(5, cA4_EEECE1.getCellStyle().getCoreXf().getFillId());
-       assertEquals(6, cA5_1F497D.getCellStyle().getCoreXf().getFillId());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51222.xlsx");
+        XSSFSheet s = wb.getSheetAt(0);
 
-       // These should reference themes 2 and 3
-       assertEquals(2, wb.getStylesSource().getFillAt(5).getCTFill().getPatternFill().getFgColor().getTheme());
-       assertEquals(3, wb.getStylesSource().getFillAt(6).getCTFill().getPatternFill().getFgColor().getTheme());
-       
-       // Ensure we get the right colours for these themes
-       // TODO fix
-//       assertEquals("FFEEECE1", wb.getTheme().getThemeColor(2).getARGBHex());
-//       assertEquals("FF1F497D", wb.getTheme().getThemeColor(3).getARGBHex());
-       
-       // Finally check the colours on the styles
-       // TODO fix
-//       assertEquals("FFEEECE1", cA4_EEECE1.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
-//       assertEquals("FF1F497D", cA5_1F497D.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
+        XSSFCell cA4_EEECE1 = s.getRow(3).getCell(0);
+        XSSFCell cA5_1F497D = s.getRow(4).getCell(0);
+
+        // Check the text
+        assertEquals("A4", cA4_EEECE1.getRichStringCellValue().getString());
+        assertEquals("A5", cA5_1F497D.getRichStringCellValue().getString());
+
+        // Check the styles assigned to them
+        assertEquals(4, cA4_EEECE1.getCTCell().getS());
+        assertEquals(5, cA5_1F497D.getCTCell().getS());
+
+        // Check we look up the correct style
+        assertEquals(4, cA4_EEECE1.getCellStyle().getIndex());
+        assertEquals(5, cA5_1F497D.getCellStyle().getIndex());
+
+        // Check the fills on them at the low level
+        assertEquals(5, cA4_EEECE1.getCellStyle().getCoreXf().getFillId());
+        assertEquals(6, cA5_1F497D.getCellStyle().getCoreXf().getFillId());
+
+        // These should reference themes 2 and 3
+        assertEquals(2, wb.getStylesSource().getFillAt(5).getCTFill().getPatternFill().getFgColor().getTheme());
+        assertEquals(3, wb.getStylesSource().getFillAt(6).getCTFill().getPatternFill().getFgColor().getTheme());
+
+        // Ensure we get the right colours for these themes
+        // TODO fix
+        // assertEquals("FFEEECE1", wb.getTheme().getThemeColor(2).getARGBHex());
+        // assertEquals("FF1F497D", wb.getTheme().getThemeColor(3).getARGBHex());
+
+        // Finally check the colours on the styles
+        // TODO fix
+        // assertEquals("FFEEECE1", cA4_EEECE1.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
+        // assertEquals("FF1F497D", cA5_1F497D.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
     }
 
     @Test
@@ -1277,90 +1207,91 @@
 
         assertEquals(rels0.get(0).getPackageRelationship(), rels1.get(0).getPackageRelationship());
     }
-    
+
     /**
      * Add comments to Sheet 1, when Sheet 2 already has
      *  comments (so /xl/comments1.xml is taken)
      */
     @Test
     public void bug51850() {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51850.xlsx");
-       XSSFSheet sh1 = wb.getSheetAt(0);
-       XSSFSheet sh2 = wb.getSheetAt(1);
- 
-       // Sheet 2 has comments
-       assertNotNull(sh2.getCommentsTable(false));
-       assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
-       
-       // Sheet 1 doesn't (yet)
-       assertNull(sh1.getCommentsTable(false));
-       
-       // Try to add comments to Sheet 1
-       CreationHelper factory = wb.getCreationHelper();
-       Drawing drawing = sh1.createDrawingPatriarch();
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51850.xlsx");
+        XSSFSheet sh1 = wb.getSheetAt(0);
+        XSSFSheet sh2 = wb.getSheetAt(1);
 
-       ClientAnchor anchor = factory.createClientAnchor();
-       anchor.setCol1(0);
-       anchor.setCol2(4);
-       anchor.setRow1(0);
-       anchor.setRow2(1);
+        // Sheet 2 has comments
+        assertNotNull(sh2.getCommentsTable(false));
+        assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
 
-       Comment comment1 = drawing.createCellComment(anchor);
-       comment1.setString(
-             factory.createRichTextString("I like this cell. It's my favourite."));
-       comment1.setAuthor("Bob T. Fish");
-       
-       anchor = factory.createClientAnchor();
-       anchor.setCol1(0);
-       anchor.setCol2(4);
-       anchor.setRow1(1);
-       anchor.setRow2(1);
-       Comment comment2 = drawing.createCellComment(anchor);
-       comment2.setString(
-             factory.createRichTextString("This is much less fun..."));
-       comment2.setAuthor("Bob T. Fish");
+        // Sheet 1 doesn't (yet)
+        assertNull(sh1.getCommentsTable(false));
 
-       Cell c1 = sh1.getRow(0).createCell(4);
-       c1.setCellValue(2.3);
-       c1.setCellComment(comment1);
-       
-       Cell c2 = sh1.getRow(0).createCell(5);
-       c2.setCellValue(2.1);
-       c2.setCellComment(comment2);
-       
-       
-       // Save and re-load
-       wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-       sh1 = wb.getSheetAt(0);
-       sh2 = wb.getSheetAt(1);
-       
-       // Check the comments
-       assertNotNull(sh2.getCommentsTable(false));
-       assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
-       
-       assertNotNull(sh1.getCommentsTable(false));
-       assertEquals(2, sh1.getCommentsTable(false).getNumberOfComments());
+        // Try to add comments to Sheet 1
+        CreationHelper factory = wb.getCreationHelper();
+        Drawing drawing = sh1.createDrawingPatriarch();
+
+        ClientAnchor anchor = factory.createClientAnchor();
+        anchor.setCol1(0);
+        anchor.setCol2(4);
+        anchor.setRow1(0);
+        anchor.setRow2(1);
+
+        Comment comment1 = drawing.createCellComment(anchor);
+        comment1.setString(
+                factory.createRichTextString("I like this cell. It's my favourite."));
+        comment1.setAuthor("Bob T. Fish");
+
+        anchor = factory.createClientAnchor();
+        anchor.setCol1(0);
+        anchor.setCol2(4);
+        anchor.setRow1(1);
+        anchor.setRow2(1);
+        Comment comment2 = drawing.createCellComment(anchor);
+        comment2.setString(
+                factory.createRichTextString("This is much less fun..."));
+        comment2.setAuthor("Bob T. Fish");
+
+        Cell c1 = sh1.getRow(0).createCell(4);
+        c1.setCellValue(2.3);
+        c1.setCellComment(comment1);
+
+        Cell c2 = sh1.getRow(0).createCell(5);
+        c2.setCellValue(2.1);
+        c2.setCellComment(comment2);
+
+
+        // Save and re-load
+        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh1 = wb.getSheetAt(0);
+        sh2 = wb.getSheetAt(1);
+
+        // Check the comments
+        assertNotNull(sh2.getCommentsTable(false));
+        assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());
+
+        assertNotNull(sh1.getCommentsTable(false));
+        assertEquals(2, sh1.getCommentsTable(false).getNumberOfComments());
     }
-    
+
     /**
      * Sheet names with a , in them
      */
     @Test
     public void bug51963() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51963.xlsx");
-       XSSFSheet sheet = wb.getSheetAt(0);
-       assertEquals("Abc,1", sheet.getSheetName());
-       
-       Name name = wb.getName("Intekon.ProdCodes");
-       assertEquals("'Abc,1'!$A$1:$A$2", name.getRefersToFormula());
-       
-       AreaReference ref = new AreaReference(name.getRefersToFormula());
-       assertEquals(0, ref.getFirstCell().getRow());
-       assertEquals(0, ref.getFirstCell().getCol());
-       assertEquals(1, ref.getLastCell().getRow());
-       assertEquals(0, ref.getLastCell().getCol());
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51963.xlsx");
+        Sheet sheet = wb.getSheetAt(0);
+        assertEquals("Abc,1", sheet.getSheetName());
+
+        Name name = wb.getName("Intekon.ProdCodes");
+        assertEquals("'Abc,1'!$A$1:$A$2", name.getRefersToFormula());
+
+        @SuppressWarnings("deprecation")
+        AreaReference ref = new AreaReference(name.getRefersToFormula());
+        assertEquals(0, ref.getFirstCell().getRow());
+        assertEquals(0, ref.getFirstCell().getCol());
+        assertEquals(1, ref.getLastCell().getRow());
+        assertEquals(0, ref.getLastCell().getCol());
     }
-    
+
     /**
      * Sum across multiple workbooks
      *  eg =SUM($Sheet1.C1:$Sheet4.C1)
@@ -1368,28 +1299,28 @@
      */
     @Ignore
     public void bug48703() throws Exception {
-       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48703.xlsx");
-       XSSFSheet sheet = wb.getSheetAt(0);
-       
-       // Contains two forms, one with a range and one a list
-       XSSFRow r1 = sheet.getRow(0);
-       XSSFRow r2 = sheet.getRow(1);
-       XSSFCell c1 = r1.getCell(1);
-       XSSFCell c2 = r2.getCell(1);
-       
-       assertEquals(20.0, c1.getNumericCellValue(), 0);
-       assertEquals("SUM(Sheet1!C1,Sheet2!C1,Sheet3!C1,Sheet4!C1)", c1.getCellFormula());
-       
-       assertEquals(20.0, c2.getNumericCellValue(), 0);
-       assertEquals("SUM(Sheet1:Sheet4!C1)", c2.getCellFormula());
-       
-       // Try evaluating both
-       XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
-       eval.evaluateFormulaCell(c1);
-       eval.evaluateFormulaCell(c2);
-       
-       assertEquals(20.0, c1.getNumericCellValue(), 0);
-       assertEquals(20.0, c2.getNumericCellValue(), 0);
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48703.xlsx");
+        XSSFSheet sheet = wb.getSheetAt(0);
+
+        // Contains two forms, one with a range and one a list
+        XSSFRow r1 = sheet.getRow(0);
+        XSSFRow r2 = sheet.getRow(1);
+        XSSFCell c1 = r1.getCell(1);
+        XSSFCell c2 = r2.getCell(1);
+
+        assertEquals(20.0, c1.getNumericCellValue(), 0);
+        assertEquals("SUM(Sheet1!C1,Sheet2!C1,Sheet3!C1,Sheet4!C1)", c1.getCellFormula());
+
+        assertEquals(20.0, c2.getNumericCellValue(), 0);
+        assertEquals("SUM(Sheet1:Sheet4!C1)", c2.getCellFormula());
+
+        // Try evaluating both
+        XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
+        eval.evaluateFormulaCell(c1);
+        eval.evaluateFormulaCell(c2);
+
+        assertEquals(20.0, c1.getNumericCellValue(), 0);
+        assertEquals(20.0, c2.getNumericCellValue(), 0);
     }
 
     /**
@@ -1451,6 +1382,7 @@
         Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("54436.xlsx");
         if(!WorkbookEvaluator.getSupportedFunctionNames().contains("GETPIVOTDATA")){
             Function func = new Function() {
+                @Override
                 public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
                     return ErrorEval.NA;
                 }
@@ -1463,27 +1395,33 @@
     
     /**
      * Password Protected .xlsx files should give a helpful
-     *  error message when called via WorkbookFactory.
-     * (You need to supply a password explicitly for them)
+     *  error message when called via WorkbookFactory with no password
      */
     @Test(expected=EncryptedDocumentException.class)
-    public void bug55692_stream() throws Exception {
-        // Directly on a Stream
-        WorkbookFactory.create(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
-    }
-    
-    @Test(expected=EncryptedDocumentException.class)
     public void bug55692_poifs() throws Exception {
         // Via a POIFSFileSystem
-        POIFSFileSystem fsP = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+        POIFSFileSystem fsP = new POIFSFileSystem(
+                POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
         WorkbookFactory.create(fsP);
     }
     
-    @Test(expected=EncryptedDocumentException.class)
+    public void bug55692_stream() throws Exception {
+        // Directly on a Stream, will go via NPOIFS and spot it's
+        //  actually a .xlsx file encrypted with the default password, and open
+        Workbook wb = WorkbookFactory.create(
+                POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+        assertNotNull(wb);
+        assertEquals(3, wb.getNumberOfSheets());
+    }
+    
     public void bug55692_npoifs() throws Exception {
-        // Via a NPOIFSFileSystem
-        NPOIFSFileSystem fsNP = new NPOIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
-        WorkbookFactory.create(fsNP);
+        // Via a NPOIFSFileSystem, will spot it's actually a .xlsx file
+        //  encrypted with the default password, and open
+        NPOIFSFileSystem fsNP = new NPOIFSFileSystem(
+                POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+        Workbook wb = WorkbookFactory.create(fsNP);
+        assertNotNull(wb);
+        assertEquals(3, wb.getNumberOfSheets());
     }
 
     @Test
@@ -1527,6 +1465,15 @@
         cell.setCellValue("Hi");
         sheet.setRepeatingRows(new CellRangeAddress(0, 0, 0, 0));
         
+        // small hack to try to make this test stable, previously it failed whenever the two written ZIP files had different file-creation
+        // dates stored.
+        // We try to do a loop until the current second changes in order to avoid problems with some date information that is written to the ZIP and thus
+        // causes differences
+        long start = System.currentTimeMillis()/1000;
+        while(System.currentTimeMillis()/1000 == start) {
+            Thread.sleep(10);
+        }
+        
         ByteArrayOutputStream bos = new ByteArrayOutputStream(8096);
         wb.write(bos);
         byte firstSave[] = bos.toByteArray();
@@ -1534,7 +1481,15 @@
         wb.write(bos);
         byte secondSave[] = bos.toByteArray();
         
-        assertArrayEquals(firstSave, secondSave);
+        /*OutputStream stream = new FileOutputStream("C:\\temp\\poi.xlsx");
+        try {
+            wb.write(stream);
+        } finally {
+            stream.close();
+        }*/
+        
+        assertArrayEquals("Had: \n" + Arrays.toString(firstSave) + " and \n" + Arrays.toString(secondSave),  
+                firstSave, secondSave);
         
         wb.close();
     }
@@ -1583,7 +1538,6 @@
      * SUMIF was throwing a NPE on some formulas
      */
     @Test
-    @Ignore("This bug is still to be fixed")
     public void testBug56420SumIfNPE() throws Exception {
         XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56420.xlsx");
         
@@ -1593,7 +1547,8 @@
         Row r = sheet.getRow(2);
         Cell c = r.getCell(2);
         assertEquals("SUMIF($A$1:$A$4,A3,$B$1:$B$4)", c.getCellFormula());
-        evaluator.evaluateInCell(c);
+        Cell eval = evaluator.evaluateInCell(c);
+        assertEquals(0.0, eval.getNumericCellValue(), 0.0001);
     }
 
     private void bug53798Work(Workbook wb, File xlsOutput) throws IOException {
@@ -2040,24 +1995,11 @@
         }
     }
     
-    @Test
-    public void bug57430() throws Exception {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        try {
-            wb.createSheet("Sheet1");
-
-            XSSFName name1 = wb.createName();
-            name1.setNameName("FMLA");
-            name1.setRefersToFormula("Sheet1!$B$3");
-        } finally {
-            wb.close();
-        }
-    }
-    
     /**
      * A .xlsx file with no Shared Strings table should open fine
      *  in read-only mode
      */
+    @SuppressWarnings("resource")
     @Test
     public void bug57482() throws Exception {
         for (PackageAccess access : new PackageAccess[] {
@@ -2128,4 +2070,421 @@
         assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString());
         assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString());
     }
+
+    
+    @Test
+    public void test57165() throws IOException {
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
+        try {
+            removeAllSheetsBut(3, wb);
+            wb.cloneSheet(0); // Throws exception here
+            wb.setSheetName(1, "New Sheet");
+            //saveWorkbook(wb, fileName);
+            
+            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+            try {
+                
+            } finally {
+                wbBack.close();
+            }
+        } finally {
+            wb.close();
+        }
+    }
+
+    @Test
+    public void test57165_create() throws IOException {
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
+        try {
+            removeAllSheetsBut(3, wb);
+            wb.createSheet("newsheet"); // Throws exception here
+            wb.setSheetName(1, "New Sheet");
+            //saveWorkbook(wb, fileName);
+            
+            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+            try {
+                
+            } finally {
+                wbBack.close();
+            }
+        } finally {
+            wb.close();
+        }
+    }
+
+    private static void removeAllSheetsBut(int sheetIndex, Workbook wb)
+    {
+        int sheetNb = wb.getNumberOfSheets();
+        // Move this sheet at the first position
+        wb.setSheetOrder(wb.getSheetName(sheetIndex), 0);
+        for (int sn = sheetNb - 1; sn > 0; sn--)
+        {
+            wb.removeSheetAt(sn);
+        }
+    }
+
+    /**
+     * Sums 2 plus the cell at the left, indirectly to avoid reference
+     * problems when deleting columns, conditionally to stop recursion
+     */
+    private static final String FORMULA1 =
+            "IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0,"
+                    + "INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) ) + 2";
+
+    /**
+     * Sums 2 plus the upper cell, indirectly to avoid reference
+     * problems when deleting rows, conditionally to stop recursion
+     */
+    private static final String FORMULA2 =
+            "IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0,"
+                    + "INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) ) + 2";
+
+    /**
+     * Expected:
+
+     * [  0][  2][  4]
+     * @throws IOException
+     */
+    @Test
+    public void testBug56820_Formula1() throws IOException {
+        Workbook wb = new XSSFWorkbook();
+        try {
+            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+            Sheet sh = wb.createSheet();
+
+            sh.createRow(0).createCell(0).setCellValue(0.0d);
+            Cell formulaCell1 = sh.getRow(0).createCell(1);
+            Cell formulaCell2 = sh.getRow(0).createCell(2);
+            formulaCell1.setCellFormula(FORMULA1);
+            formulaCell2.setCellFormula(FORMULA1);
+
+            double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
+            double A2 = evaluator.evaluate(formulaCell2).getNumberValue();
+
+            assertEquals(2, A1, 0);
+            assertEquals(4, A2, 0);  //<-- FAILS EXPECTATIONS
+        } finally {
+            wb.close();
+        }
+    }
+
+    /**
+     * Expected:
+
+     * [  0] <- number
+     * [  2] <- formula
+     * [  4] <- formula
+     * @throws IOException
+     */
+    @Test
+    public void testBug56820_Formula2() throws IOException {
+        Workbook wb = new XSSFWorkbook();
+        try {
+            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+            Sheet sh = wb.createSheet();
+
+            sh.createRow(0).createCell(0).setCellValue(0.0d);
+            Cell formulaCell1 = sh.createRow(1).createCell(0);
+            Cell formulaCell2 = sh.createRow(2).createCell(0);
+            formulaCell1.setCellFormula(FORMULA2);
+            formulaCell2.setCellFormula(FORMULA2);
+
+            double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
+            double A2 = evaluator.evaluate(formulaCell2).getNumberValue(); //<-- FAILS EVALUATION
+
+            assertEquals(2, A1, 0);
+            assertEquals(4, A2, 0);
+        } finally {
+            wb.close();
+        }
+    }
+    
+    @Test
+    public void test56467() throws IOException {
+        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("picture.xlsx");
+        try {
+            Sheet orig = wb.getSheetAt(0);
+            assertNotNull(orig);
+            
+            Sheet sheet = wb.cloneSheet(0);
+            Drawing drawing = sheet.createDrawingPatriarch();
+            for (XSSFShape shape : ((XSSFDrawing) drawing).getShapes()) {
+                if (shape instanceof XSSFPicture) {
+                    XSSFPictureData pictureData = ((XSSFPicture) shape).getPictureData();
+                    assertNotNull(pictureData);
+                }
+            }
+            
+//            OutputStream out = new FileOutputStream("/tmp/56467.xls");
+//            try {
+//            	wb.write(out);
+//            } finally {
+//            	out.close();
+//            }
+        } finally {
+        	wb.close();
+        }
+    }
+    
+    /**
+     * OOXML-Strict files
+     * Not currently working - namespace mis-match from XMLBeans
+     */
+    @Test
+    @Ignore("XMLBeans namespace mis-match on ooxml-strict files")
+    public void test57699() throws Exception {
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.strict.xlsx");
+        assertEquals(3, wb.getNumberOfSheets());
+        // TODO Check sheet contents
+        // TODO Check formula evaluation
+        
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertEquals(3, wbBack.getNumberOfSheets());
+        // TODO Re-check sheet contents
+        // TODO Re-check formula evaluation
+    }
+
+    @Test
+    public void testBug56295_MergeXlslsWithStyles() throws IOException {
+        XSSFWorkbook xlsToAppendWorkbook = XSSFTestDataSamples.openSampleWorkbook("56295.xlsx");
+        XSSFSheet sheet = xlsToAppendWorkbook.getSheetAt(0);
+        XSSFRow srcRow = sheet.getRow(0);
+        XSSFCell oldCell = srcRow.getCell(0);
+        XSSFCellStyle cellStyle = oldCell.getCellStyle();
+        
+        checkStyle(cellStyle);
+        
+//        StylesTable table = xlsToAppendWorkbook.getStylesSource();
+//        List<XSSFCellFill> fills = table.getFills();
+//        System.out.println("Having " + fills.size() + " fills");
+//        for(XSSFCellFill fill : fills) {
+//        	System.out.println("Fill: " + fill.getFillBackgroundColor() + "/" + fill.getFillForegroundColor());
+//        }        
+        
+        XSSFWorkbook targetWorkbook = new XSSFWorkbook();
+        XSSFSheet newSheet = targetWorkbook.createSheet(sheet.getSheetName());
+        XSSFRow destRow = newSheet.createRow(0);
+        XSSFCell newCell = destRow.createCell(0);
+
+		//newCell.getCellStyle().cloneStyleFrom(cellStyle);
+        CellStyle newCellStyle = targetWorkbook.createCellStyle();
+        newCellStyle.cloneStyleFrom(cellStyle);
+        newCell.setCellStyle(newCellStyle);
+		checkStyle(newCell.getCellStyle());
+        newCell.setCellValue(oldCell.getStringCellValue());
+
+//        OutputStream os = new FileOutputStream("output.xlsm");
+//        try {
+//        	targetWorkbook.write(os);
+//        } finally {
+//        	os.close();
+//        }
+        
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(targetWorkbook);
+        XSSFCellStyle styleBack = wbBack.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
+        checkStyle(styleBack);
+    }
+
+    /**
+     * Paragraph with property BuFont but none of the properties 
+     *  BuNone, BuChar, and BuAutoNum, used to trigger a NPE
+     * Excel treats this as not-bulleted, so now do we
+     */
+    @Test
+    public void testBug57826() {
+        XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("57826.xlsx");
+
+        assertTrue("no sheets in workbook", workbook.getNumberOfSheets() >= 1);
+        XSSFSheet sheet = workbook.getSheetAt(0);
+
+        XSSFDrawing drawing = sheet.getDrawingPatriarch();
+        assertNotNull(drawing);
+
+        List<XSSFShape> shapes = drawing.getShapes();
+        assertEquals(1, shapes.size());
+        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
+
+        XSSFSimpleShape shape = (XSSFSimpleShape)shapes.get(0);
+
+        // Used to throw a NPE
+        String text = shape.getText();
+
+        // No bulleting info included
+        assertEquals("test ok", text);
+    }
+
+	private void checkStyle(XSSFCellStyle cellStyle) {
+		assertNotNull(cellStyle);
+        assertEquals(0, cellStyle.getFillForegroundColor());
+        assertNotNull(cellStyle.getFillForegroundXSSFColor());
+        XSSFColor fgColor = cellStyle.getFillForegroundColorColor();
+		assertNotNull(fgColor);
+		assertEquals("FF00FFFF", fgColor.getARGBHex());
+
+        assertEquals(0, cellStyle.getFillBackgroundColor());
+        assertNotNull(cellStyle.getFillBackgroundXSSFColor());
+        XSSFColor bgColor = cellStyle.getFillBackgroundColorColor();
+		assertNotNull(bgColor);
+		assertEquals("FF00FFFF", fgColor.getARGBHex());
+	}
+
+    @Test
+    public void bug57642() throws Exception {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet s = wb.createSheet("TestSheet");
+        XSSFCell c = s.createRow(0).createCell(0);
+        c.setCellFormula("ISERROR(TestSheet!A1)");
+        c = s.createRow(1).createCell(1);
+        c.setCellFormula("ISERROR(B2)");
+
+        wb.setSheetName(0, "CSN");
+        c = s.getRow(0).getCell(0);
+        assertEquals("ISERROR(CSN!A1)", c.getCellFormula());
+        c = s.getRow(1).getCell(1);
+        assertEquals("ISERROR(B2)", c.getCellFormula());
+        
+        wb.close();
+    }
+
+    /**
+     * .xlsx supports 64000 cell styles, the style indexes after
+     *  32,767 must not be -32,768, then -32,767, -32,766
+     */
+    @Test
+    public void bug57880() throws Exception {
+        int numStyles = 33000;
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet s = wb.createSheet("TestSheet");
+        XSSFDataFormat fmt = wb.getCreationHelper().createDataFormat();
+        for (int i=1; i<numStyles; i++) {
+            short df = fmt.getFormat("test"+i);
+            // Format indexes will be wrapped beyond 32,676
+            assertEquals(164+i, df&0xffff);
+            // Create a style and use it
+            XSSFCellStyle style = wb.createCellStyle();
+            assertEquals(i, style.getUIndex());
+            style.setDataFormat(df);
+            XSSFCell c = s.createRow(i).createCell(0, Cell.CELL_TYPE_NUMERIC);
+            c.setCellStyle(style);
+            c.setCellValue(i);
+        }
+        
+        // using temp file instead of ByteArrayOutputStream because of OOM in gump run
+        File tmp = TempFile.createTempFile("poi-test", ".bug57880");
+        FileOutputStream fos = new FileOutputStream(tmp);
+        wb.write(fos);
+        fos.close();
+        
+        wb.close();
+        fmt = null; s = null; wb = null;
+        // System.gc();
+        
+        wb = new XSSFWorkbook(tmp);
+        fmt = wb.getCreationHelper().createDataFormat();
+        s = wb.getSheetAt(0);
+        for (int i=1; i<numStyles; i++) {
+            XSSFCellStyle style = wb.getCellStyleAt((short)i);
+            assertNotNull(style);
+            assertEquals(i, style.getUIndex());
+            assertEquals(164+i, style.getDataFormat()&0xffff);
+            assertEquals("test"+i, style.getDataFormatString());
+        }
+        wb.close();
+        tmp.delete();
+    }
+
+
+    @Test
+    public void test56574() throws IOException {
+        runTest56574(false);
+        runTest56574(true);
+    }
+
+    @SuppressWarnings("deprecation")
+    private void runTest56574(boolean createRow) throws IOException {
+        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56574.xlsx");
+
+        Sheet sheet = wb.getSheet("Func");
+        assertNotNull(sheet);
+
+        Map<String, Object[]> data;
+        data = new TreeMap<String, Object[]>();
+        data.put("1", new Object[] {"ID", "NAME", "LASTNAME"});
+        data.put("2", new Object[] {2, "Amit", "Shukla"});
+        data.put("3", new Object[] {1, "Lokesh", "Gupta"});
+        data.put("4", new Object[] {4, "John", "Adwards"});
+        data.put("5", new Object[] {2, "Brian", "Schultz"});
+        
+        Set<String> keyset = data.keySet();
+        int rownum = 1;
+        for (String key : keyset)
+        {
+            final Row row;
+            if(createRow) {
+                row = sheet.createRow(rownum++);
+            } else {
+                row = sheet.getRow(rownum++);
+            }
+            assertNotNull(row);
+
+            Object [] objArr = data.get(key);
+            int cellnum = 0;
+            for (Object obj : objArr)
+            {
+                Cell cell = row.getCell(cellnum);
+                if(cell == null){
+                    cell = row.createCell(cellnum);
+                } else {
+                    if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
+                        cell.setCellFormula(null);
+                        cell.getCellStyle().setDataFormat((short) 0);
+                    }
+                }
+               if(obj instanceof String) {
+                    cell.setCellValue((String)obj);
+               } else if(obj instanceof Integer) {
+                    cell.setCellValue((Integer)obj);
+               }
+               cellnum++;
+            }
+        }
+
+        XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) wb);
+        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+
+        CalculationChain chain = ((XSSFWorkbook)wb).getCalculationChain();
+        CTCalcCell[] cArray = chain.getCTCalcChain().getCArray();
+        for(CTCalcCell calc : cArray) {
+            // A2 to A6 should be gone
+            assertFalse(calc.getR().equals("A2"));
+            assertFalse(calc.getR().equals("A3"));
+            assertFalse(calc.getR().equals("A4"));
+            assertFalse(calc.getR().equals("A5"));
+            assertFalse(calc.getR().equals("A6"));
+        }
+        
+        /*FileOutputStream out = new FileOutputStream(new File("C:\\temp\\56574.xlsx"));
+        try {
+            wb.write(out);
+        } finally {
+            out.close();
+        }*/
+        
+        Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        Sheet sheetBack = wbBack.getSheet("Func");
+        assertNotNull(sheetBack);
+
+        chain = ((XSSFWorkbook)wbBack).getCalculationChain();
+        cArray = chain.getCTCalcChain().getCArray();
+        for(CTCalcCell calc : cArray) {
+            // A2 to A6 should be gone
+            assertFalse(calc.getR().equals("A2"));
+            assertFalse(calc.getR().equals("A3"));
+            assertFalse(calc.getR().equals("A4"));
+            assertFalse(calc.getR().equals("A5"));
+            assertFalse(calc.getR().equals("A6"));
+        }
+        
+        wb.close();
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java
index 9740e41..1d020e9 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java
@@ -19,6 +19,8 @@
 
 import java.io.IOException;
 
+import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.usermodel.BaseTestXCell;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.DataFormatter;
@@ -28,6 +30,7 @@
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xssf.SXSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.SharedStringsTable;
@@ -402,4 +405,48 @@
             wb.close();
         }
     }
+
+    public void testEncodingbeloAscii(){
+        StringBuffer sb = new StringBuffer();
+        // test all possible characters
+        for(int i = 0; i < Character.MAX_VALUE; i++) {
+        	sb.append((char)i);
+        }
+
+        String strAll = sb.toString();
+
+        // process in chunks as we have a limit on size of column now
+        int pos = 0;
+        while(pos < strAll.length()) {
+        	String str = strAll.substring(pos, Math.min(strAll.length(), pos+SpreadsheetVersion.EXCEL2007.getMaxTextLength()));
+        	
+            Workbook wb = HSSFITestDataProvider.instance.createWorkbook();
+            Cell cell = wb.createSheet().createRow(0).createCell(0);
+            
+            Workbook xwb = XSSFITestDataProvider.instance.createWorkbook();
+            Cell xCell = xwb.createSheet().createRow(0).createCell(0);
+
+            Workbook swb = SXSSFITestDataProvider.instance.createWorkbook();
+            Cell sCell = swb.createSheet().createRow(0).createCell(0);
+
+        	cell.setCellValue(str);
+        	assertEquals(str, cell.getStringCellValue());
+        	xCell.setCellValue(str);
+        	assertEquals(str, xCell.getStringCellValue());
+        	sCell.setCellValue(str);
+        	assertEquals(str, sCell.getStringCellValue());
+        	
+        	Workbook wbBack = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+        	Workbook xwbBack = XSSFITestDataProvider.instance.writeOutAndReadBack(xwb);
+        	Workbook swbBack = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb);
+        	cell = wbBack.getSheetAt(0).createRow(0).createCell(0);
+        	xCell = xwbBack.getSheetAt(0).createRow(0).createCell(0);
+        	sCell = swbBack.getSheetAt(0).createRow(0).createCell(0);
+        	
+        	assertEquals(cell.getStringCellValue(), xCell.getStringCellValue());
+        	assertEquals(cell.getStringCellValue(), sCell.getStringCellValue());
+        	
+        	pos += SpreadsheetVersion.EXCEL97.getMaxTextLength();
+        }
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
index 8d427be..6c7893e 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
@@ -17,20 +17,26 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import java.io.IOException;
+
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
 import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.ss.usermodel.IndexedColors;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.StylesTable;
 import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;
 import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
+import org.junit.Test;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 
 public class TestXSSFCellStyle extends TestCase {
@@ -82,6 +88,9 @@
 		stylesTable.putCellStyleXf(cellStyleXf);
 		stylesTable.putCellXf(cellXf);
 		cellStyle = new XSSFCellStyle(1, 1, stylesTable, null);
+
+		assertNotNull(stylesTable.getFillAt(1).getCTFill().getPatternFill());
+		assertEquals(STPatternType.INT_DARK_GRAY, stylesTable.getFillAt(1).getCTFill().getPatternFill().getPatternType().intValue());
 	}
 
 	public void testGetSetBorderBottom() {
@@ -551,7 +560,7 @@
         assertEquals(IndexedColors.AUTOMATIC.getIndex(), cellStyle.getFillBackgroundColor());
 	}
 
-	public void testDefaultStyles() {
+	public void testDefaultStyles() throws IOException {
 
 		XSSFWorkbook wb1 = new XSSFWorkbook();
 
@@ -577,6 +586,7 @@
         assertEquals(style2.getBorderLeft(), style1.getBorderLeft());
         assertEquals(style2.getBorderRight(), style1.getBorderRight());
         assertEquals(style2.getBorderTop(), style1.getBorderTop());
+        wb2.close();
 	}
 
 
@@ -618,7 +628,7 @@
 
 	public void testGetFillPattern() {
 
-        assertEquals(CellStyle.NO_FILL, cellStyle.getFillPattern());
+        assertEquals(STPatternType.INT_DARK_GRAY-1, cellStyle.getFillPattern());
 
         int num = stylesTable.getFills().size();
         cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
@@ -885,4 +895,50 @@
         assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb));
         assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wbOrig));
     }
+    
+    @Test
+    public void testSetColor() throws IOException {
+        Workbook wb = new XSSFWorkbook();
+        Sheet sheet = wb.createSheet();
+        Row row = sheet.createRow(0);
+        
+        //CreationHelper ch = wb.getCreationHelper();
+        DataFormat format = wb.createDataFormat();
+        Cell cell = row.createCell(1);
+        cell.setCellValue("somevalue");
+        CellStyle cellStyle = wb.createCellStyle();
+
+
+        cellStyle.setDataFormat(format.getFormat("###0"));
+
+        cellStyle.setFillBackgroundColor(IndexedColors.DARK_BLUE.getIndex());
+        cellStyle.setFillForegroundColor(IndexedColors.DARK_BLUE.getIndex());
+        cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
+
+        cellStyle.setAlignment(CellStyle.ALIGN_RIGHT);
+        cellStyle.setVerticalAlignment(CellStyle.VERTICAL_TOP);
+
+        cell.setCellStyle(cellStyle);
+
+        /*OutputStream stream = new FileOutputStream("C:\\temp\\CellColor.xlsx");
+        try {
+            wb.write(stream);
+        } finally {
+            stream.close();
+        }*/
+        
+        Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        Cell cellBack = wbBack.getSheetAt(0).getRow(0).getCell(1);
+        assertNotNull(cellBack);
+        CellStyle styleBack = cellBack.getCellStyle();
+        assertEquals(IndexedColors.DARK_BLUE.getIndex(), styleBack.getFillBackgroundColor());
+        assertEquals(IndexedColors.DARK_BLUE.getIndex(), styleBack.getFillForegroundColor());
+        assertEquals(CellStyle.ALIGN_RIGHT, styleBack.getAlignment());
+        assertEquals(CellStyle.VERTICAL_TOP, styleBack.getVerticalAlignment());
+        assertEquals(CellStyle.SOLID_FOREGROUND, styleBack.getFillPattern());
+        
+        wbBack.close();
+        
+        wb.close();
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java
index 325c534..8122035 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java
@@ -19,17 +19,32 @@
 package org.apache.poi.xssf.usermodel;

 

 import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting;

+import org.apache.poi.ss.usermodel.Color;

 import org.apache.poi.xssf.XSSFITestDataProvider;

 

 /**

- * @author Yegor Kozlov

+ * XSSF-specific Conditional Formatting tests

  */

 public class TestXSSFConditionalFormatting extends BaseTestConditionalFormatting {

     public TestXSSFConditionalFormatting(){

         super(XSSFITestDataProvider.instance);

     }

 

+    protected void assertColour(String hexExpected, Color actual) {

+        assertNotNull("Colour must be given", actual);

+        XSSFColor colour = (XSSFColor)actual;

+        if (hexExpected.length() == 8) {

+            assertEquals(hexExpected, colour.getARGBHex());

+        } else {

+            assertEquals(hexExpected, colour.getARGBHex().substring(2));

+        }

+    }

+

     public void testRead(){

         testRead("WithConditionalFormatting.xlsx");

     }

+    

+    public void testReadOffice2007() {

+        testReadOffice2007("NewStyleConditionalFormattings.xlsx");

+    }

 }

diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java
index 3bbe6f2..e0dbcaa 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java
@@ -17,6 +17,8 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import java.io.IOException;
+
 import org.apache.poi.POIXMLException;
 import org.apache.poi.ss.usermodel.BaseTestFont;
 import org.apache.poi.ss.usermodel.Font;
@@ -25,6 +27,8 @@
 import org.apache.poi.ss.usermodel.FontScheme;
 import org.apache.poi.ss.usermodel.FontUnderline;
 import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.SheetUtil;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty;
@@ -88,6 +92,8 @@
       // And set with the Charset index
       xssfFont.setCharSet(FontCharset.ARABIC.getValue());
       assertEquals(FontCharset.ARABIC.getValue(), xssfFont.getCharSet());
+      xssfFont.setCharSet((byte)(FontCharset.ARABIC.getValue()));
+      assertEquals(FontCharset.ARABIC.getValue(), xssfFont.getCharSet());
       
       // This one isn't allowed
       assertEquals(null, FontCharset.valueOf(9999));
@@ -279,4 +285,23 @@
 		font.setTypeOffset(XSSFFont.SS_SUPER);
 		assertEquals(STVerticalAlignRun.SUPERSCRIPT,ctFont.getVertAlignArray(0).getVal());
 	}
+
+	// store test from TestSheetUtil here as it uses XSSF
+    public void testCanComputeWidthXSSF() throws IOException {
+        Workbook wb = new XSSFWorkbook();
+
+        // cannot check on result because on some machines we get back false here!
+        SheetUtil.canComputeColumnWidht(wb.getFontAt((short)0));
+
+        wb.close();        
+    }
+
+    // store test from TestSheetUtil here as it uses XSSF
+    public void testCanComputeWidthInvalidFont() throws IOException {
+        Font font = new XSSFFont(CTFont.Factory.newInstance());
+        font.setFontName("some non existing font name");
+        
+        // Even with invalid fonts we still get back useful data most of the time... 
+        SheetUtil.canComputeColumnWidht(font);
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java
index c2a7597..d56005a 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java
@@ -25,6 +25,7 @@
 import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellValue;
+import org.apache.poi.ss.usermodel.FormulaError;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -186,28 +187,32 @@
         
         // Link and re-try
         Workbook alt = new XSSFWorkbook();
-        alt.createSheet().createRow(0).createCell(0).setCellValue("In another workbook");
-        // TODO Implement the rest of this, see bug #57184
-/*
-        wb.linkExternalWorkbook("alt.xlsx", alt);
-                
-        cXSLX_nw_cell.setCellFormula("[alt.xlsx]Sheet1!$A$1");
-        // Check it - TODO Is this correct? Or should it become [3]Sheet1!$A$1 ?
-        assertEquals("[alt.xlsx]Sheet1!$A$1", cXSLX_nw_cell.getCellFormula());
-        
-        // Evaluate it, without a link to that workbook
         try {
+            alt.createSheet().createRow(0).createCell(0).setCellValue("In another workbook");
+            // TODO Implement the rest of this, see bug #57184
+/*
+            wb.linkExternalWorkbook("alt.xlsx", alt);
+                    
+            cXSLX_nw_cell.setCellFormula("[alt.xlsx]Sheet1!$A$1");
+            // Check it - TODO Is this correct? Or should it become [3]Sheet1!$A$1 ?
+            assertEquals("[alt.xlsx]Sheet1!$A$1", cXSLX_nw_cell.getCellFormula());
+            
+            // Evaluate it, without a link to that workbook
+            try {
+                evaluator.evaluate(cXSLX_nw_cell);
+                fail("No cached value and no link to workbook, shouldn't evaluate");
+            } catch(Exception e) {}
+            
+            // Add a link, check it does
+            evaluators.put("alt.xlsx", alt.getCreationHelper().createFormulaEvaluator());
+            evaluator.setupReferencedWorkbooks(evaluators);
+            
             evaluator.evaluate(cXSLX_nw_cell);
-            fail("No cached value and no link to workbook, shouldn't evaluate");
-        } catch(Exception e) {}
-        
-        // Add a link, check it does
-        evaluators.put("alt.xlsx", alt.getCreationHelper().createFormulaEvaluator());
-        evaluator.setupReferencedWorkbooks(evaluators);
-        
-        evaluator.evaluate(cXSLX_nw_cell);
-        assertEquals("In another workbook", cXSLX_nw_cell.getStringCellValue());
+            assertEquals("In another workbook", cXSLX_nw_cell.getStringCellValue());
 */
+        } finally {
+        	alt.close();
+        }
     }
     
     /**
@@ -519,7 +524,6 @@
         }
     }
     
-
     public void testBug55843f() throws IOException {
         XSSFWorkbook wb = new XSSFWorkbook();
         try {
@@ -539,4 +543,68 @@
             wb.close();
         }
     }    
+
+    public void testBug56655() throws IOException {
+        Workbook wb =  new XSSFWorkbook();
+        Sheet sheet = wb.createSheet();
+        
+        setCellFormula(sheet, 0, 0, "#VALUE!");
+        setCellFormula(sheet, 0, 1, "SUMIFS(A:A,A:A,#VALUE!)");
+
+        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+
+        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0,0).getCachedFormulaResultType());
+        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,0).getErrorCellValue());
+        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0,1).getCachedFormulaResultType());
+        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0,1).getErrorCellValue());
+        
+        wb.close();
+    }
+
+    public void testBug56655a() throws IOException {
+        Workbook wb =  new XSSFWorkbook();
+        Sheet sheet = wb.createSheet();
+        
+        setCellFormula(sheet, 0, 0, "B1*C1");
+        sheet.getRow(0).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 1, 0, "B1*C1");
+        sheet.getRow(1).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 0, 3, "SUMIFS(A:A,A:A,A2)");
+
+        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+
+        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0, 0).getCachedFormulaResultType());
+        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 0).getErrorCellValue());
+        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 1, 0).getCachedFormulaResultType());
+        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 1, 0).getErrorCellValue());
+        assertEquals(XSSFCell.CELL_TYPE_ERROR, getCell(sheet, 0, 3).getCachedFormulaResultType());
+        assertEquals(FormulaError.VALUE.getCode(), getCell(sheet, 0, 3).getErrorCellValue());
+        
+        wb.close();
+    }
+
+    /**
+    * @param row 0-based
+    * @param column 0-based
+    */
+   private void setCellFormula(Sheet sheet, int row, int column, String formula) {
+       Row r = sheet.getRow(row);
+       if (r == null) {
+           r = sheet.createRow(row);
+       }
+       Cell cell = r.getCell(column);
+       if (cell == null) {
+           cell = r.createCell(column);
+       }
+       cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
+       cell.setCellFormula(formula);
+   }
+
+   /**
+    * @param rowNo 0-based
+    * @param column 0-based
+    */
+   private Cell getCell(Sheet sheet, int rowNo, int column) {
+       return sheet.getRow(rowNo).getCell(column);
+   }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java
index fe06afc..df56819 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java
@@ -92,8 +92,8 @@
         assertNotNull(p3);
 
         //check that the added pictures are accessible after write
-        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-        List<XSSFPictureData> pictures2 = wb.getAllPictures();
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
+        List<XSSFPictureData> pictures2 = wbBack.getAllPictures();
         assertEquals(3, pictures2.size());
 
         assertEquals("jpeg", pictures2.get(jpegIdx).suggestFileExtension());
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java
index 3001197..6cda3af 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPrintSetup.java
@@ -19,12 +19,18 @@
 
 import junit.framework.TestCase;
 
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
-import org.apache.poi.ss.usermodel.PaperSize;
 import org.apache.poi.ss.usermodel.PageOrder;
-import org.apache.poi.ss.usermodel.PrintOrientation;
+import org.apache.poi.ss.usermodel.PaperSize;
 import org.apache.poi.ss.usermodel.PrintCellComments;
+import org.apache.poi.ss.usermodel.PrintOrientation;
 import org.apache.poi.xssf.XSSFITestDataProvider;
+import org.junit.Test;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetup;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellComments;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STOrientation;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPageOrder;
 
 /**
  * Tests for {@link XSSFPrintSetup}
@@ -226,10 +232,10 @@
        assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
        
        // Round trip and check
-       wb = XSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+       XSSFWorkbook wbBack = XSSFITestDataProvider.instance.writeOutAndReadBack(wb);
        
-       s1 = wb.getSheetAt(0);
-       s2 = wb.getSheetAt(1);
+       s1 = wbBack.getSheetAt(0);
+       s2 = wbBack.getSheetAt(1);
        
        assertEquals(true, s1.getCTWorksheet().isSetPageSetup());
        assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
@@ -239,6 +245,8 @@
        print = s1.getPrintSetup();
        assertEquals(3, print.getCopies());
        assertEquals(true, print.getLandscape());
+       
+       wb.close();
     }
 
     /**
@@ -248,4 +256,30 @@
     public void testRoundTrip() {
        // TODO
     }
+
+    @Test
+    public void testSetLandscapeFalse() throws Exception {
+        XSSFPrintSetup ps = new XSSFPrintSetup(CTWorksheet.Factory.newInstance());
+        
+        assertFalse(ps.getLandscape());
+        
+        ps.setLandscape(true);
+        assertTrue(ps.getLandscape());
+        
+        ps.setLandscape(false);
+        assertFalse(ps.getLandscape());
+    }
+
+    @Test
+    public void testSetLeftToRight() throws Exception {
+        XSSFPrintSetup ps = new XSSFPrintSetup(CTWorksheet.Factory.newInstance());
+        
+        assertFalse(ps.getLeftToRight());
+        
+        ps.setLeftToRight(true);
+        assertTrue(ps.getLeftToRight());
+        
+        ps.setLeftToRight(false);
+        assertFalse(ps.getLeftToRight());
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
index d8f56f8..785af69 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
@@ -36,21 +36,17 @@
 import org.apache.poi.ss.usermodel.AutoFilter;
 import org.apache.poi.ss.usermodel.BaseTestSheet;
 import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CreationHelper;
-import org.apache.poi.ss.usermodel.RichTextString;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.xssf.SXSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.CalculationChain;
 import org.apache.poi.xssf.model.CommentsTable;
 import org.apache.poi.xssf.model.StylesTable;
-import org.apache.poi.xssf.streaming.SXSSFSheet;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
 import org.junit.Test;
@@ -60,8 +56,6 @@
 @SuppressWarnings("resource")
 public final class TestXSSFSheet extends BaseTestSheet {
 
-    private static final int ROW_COUNT = 40000;
-
     public TestXSSFSheet() {
         super(XSSFITestDataProvider.instance);
     }
@@ -188,39 +182,6 @@
         assertTrue(col.getBestFit());
     }
 
-    /**
-     * XSSFSheet autoSizeColumn() on empty RichTextString fails
-     */
-    @Test
-    public void bug48325() {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet("Test");
-        CreationHelper factory = wb.getCreationHelper();
-
-        XSSFRow row = sheet.createRow(0);
-        XSSFCell cell = row.createCell(0);
-
-        XSSFFont font = wb.createFont();
-        RichTextString rts = factory.createRichTextString("");
-        rts.applyFont(font);
-        cell.setCellValue(rts);
-
-        sheet.autoSizeColumn(0);
-    }
-
-    @Test
-    public void getCellComment() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet();
-        XSSFDrawing dg = sheet.createDrawingPatriarch();
-        XSSFComment comment = dg.createCellComment(new XSSFClientAnchor());
-        XSSFCell cell = sheet.createRow(9).createCell(2);
-        comment.setAuthor("test C10 author");
-        cell.setCellComment(comment);
-
-        assertNotNull(sheet.getCellComment(9, 2));
-        assertEquals("test C10 author", sheet.getCellComment(9, 2).getAuthor());
-    }
 
     @Test
     public void setCellComment() {
@@ -269,16 +230,6 @@
     }
 
     @Test
-    public void newMergedRegionAt() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet();
-        CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
-        sheet.addMergedRegion(region);
-        assertEquals("B2:D4", sheet.getMergedRegion(0).formatAsString());
-        assertEquals(1, sheet.getNumMergedRegions());
-    }
-
-    @Test
     public void removeMergedRegion_lowlevel() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         XSSFSheet sheet = workbook.createSheet();
@@ -1245,53 +1196,6 @@
     }
 
     @Test
-    public void showInPaneManyRowsBug55248() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet("Sheet 1");
-
-        sheet.showInPane(0, 0);
-
-        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
-            sheet.createRow(i);
-            sheet.showInPane(i, 0);
-            // this one fails: sheet.showInPane((short)i, 0);
-        }
-
-        int i = 0;
-        sheet.showInPane(i, i);
-
-        XSSFWorkbook wb = XSSFTestDataSamples.writeOutAndReadBack(workbook);
-        checkRowCount(wb);
-    }
-
-    @Test
-    public void showInPaneManyRowsBug55248SXSSF() {
-        SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook());
-        SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet("Sheet 1");
-
-        sheet.showInPane(0, 0);
-
-        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
-            sheet.createRow(i);
-            sheet.showInPane(i, 0);
-            // this one fails: sheet.showInPane((short)i, 0);
-        }
-
-        int i = 0;
-        sheet.showInPane(i, i);
-
-        Workbook wb = SXSSFITestDataProvider.instance.writeOutAndReadBack(workbook);
-        checkRowCount(wb);
-    }
-
-    private void checkRowCount(Workbook wb) {
-        assertNotNull(wb);
-        final Sheet sh = wb.getSheet("Sheet 1");
-        assertNotNull(sh);
-        assertEquals(ROW_COUNT-1, sh.getLastRowNum());
-    }
-
-    @Test
     public void bug55745() throws Exception {
         XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55745.xlsx");
         XSSFSheet sheet = wb.getSheetAt(0);
@@ -1472,16 +1376,4 @@
         XSSFSheet sheet = wb.createSheet();
         assertNotNull(sheet.createComment());
     }
-    
-    @Test
-    public void testRightToLeft() {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet();
-
-        assertFalse(sheet.isRightToLeft());
-        sheet.setRightToLeft(true);
-        assertTrue(sheet.isRightToLeft());
-        sheet.setRightToLeft(false);
-        assertFalse(sheet.isRightToLeft());
-    }
 }
\ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java
new file mode 100644
index 0000000..416c621
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetMergeRegions.java
@@ -0,0 +1,48 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.xssf.usermodel;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.junit.Test;
+
+public class TestXSSFSheetMergeRegions {
+    @Test
+    public void testMergeRegionsSpeed() throws IOException {
+        final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57893-many-merges.xlsx");
+        try {
+            final XSSFSheet sheet = wb.getSheetAt(0);
+            final long start = System.currentTimeMillis();
+            final List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
+            assertEquals(50000, mergedRegions.size());
+            for (CellRangeAddress cellRangeAddress : mergedRegions) {
+                assertEquals(cellRangeAddress.getFirstRow(), cellRangeAddress.getLastRow());
+                assertEquals(2, cellRangeAddress.getNumberOfCells());
+            }
+            long millis = System.currentTimeMillis() - start;
+            // This time is typically ~800ms, versus ~7800ms to iterate getMergedRegion(int).
+            assertTrue("Should have taken <2000 ms to iterate 50k merged regions but took " + millis, millis < 2000);
+        } finally {
+            wb.close();
+        }
+    }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
index e949dd1..8936446 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
@@ -25,7 +25,6 @@
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellUtil;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -44,11 +43,6 @@
         // TODO - support shifting of page breaks
     }
 
-    @Override
-	public void testShiftWithComments() { // disabled test from superclass
-        // TODO - support shifting of comments.
-    }
-
 	public void testBug54524() throws IOException {
         XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("54524.xlsx");
         XSSFSheet sheet = workbook.getSheetAt(0);
@@ -61,7 +55,6 @@
 		cell = CellUtil.getCell(sheet.getRow(3), 0);
 		assertEquals("X", cell.getStringCellValue());
 	}
-	
 
 	public void testBug53798() throws IOException {
 		// NOTE that for HSSF (.xls) negative shifts combined with positive ones do work as expected  
@@ -189,19 +182,6 @@
         assertEquals("Amdocs:\ntest\n", comment.getString().getString());
 	}
 
-	public void testBug55280() throws IOException {
-        Workbook w = new XSSFWorkbook();
-        try {
-            Sheet s = w.createSheet();
-            for (int row = 0; row < 5000; ++row)
-                s.addMergedRegion(new CellRangeAddress(row, row, 0, 3));
-
-            s.shiftRows(0, 4999, 1);        // takes a long time...
-        } finally {
-            w.close();
-        }
-	}
-
     public void test57171() throws Exception {
 	    Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
         assertEquals(5, wb.getActiveSheetIndex());
@@ -352,4 +332,38 @@
             wb.removeSheetAt(sn);
         }
     }
+
+    public void testBug57828_OnlyOneCommentShiftedInRow() throws IOException {
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57828.xlsx");
+        XSSFSheet sheet = wb.getSheetAt(0);
+
+        Comment comment1 = sheet.getCellComment(2, 1);
+        assertNotNull(comment1);
+
+        Comment comment2 = sheet.getCellComment(2, 2);
+        assertNotNull(comment2);
+
+        Comment comment3 = sheet.getCellComment(1, 1);
+        assertNull("NO comment in (1,1) and it should be null", comment3);
+
+        sheet.shiftRows(2, 2, -1);
+
+        comment3 = sheet.getCellComment(1, 1);
+        assertNotNull("Comment in (2,1) moved to (1,1) so its not null now.", comment3);
+
+        comment1 = sheet.getCellComment(2, 1);
+        assertNull("No comment currently in (2,1) and hence it is null", comment1);
+
+        comment2 = sheet.getCellComment(1, 2);
+        assertNotNull("Comment in (2,2) should have moved as well because of shift rows. But its not", comment2);
+        
+//        OutputStream stream = new FileOutputStream("/tmp/57828.xlsx");
+//        try {
+//        	wb.write(stream);
+//        } finally {
+//        	stream.close();
+//        }
+        
+        wb.close();
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java
index 346abe0..5bb3acd 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFVMLDrawing.java
@@ -54,14 +54,14 @@
         assertEquals("21600,21600", type.getCoordsize());
         assertEquals(202.0f, type.getSpt());
         assertEquals("m,l,21600r21600,l21600,xe", type.getPath2());
-        assertEquals("_xssf_cell_comment", type.getId());
+        assertEquals("_x0000_t202", type.getId());
         assertEquals(STTrueFalse.T, type.getPathArray(0).getGradientshapeok());
         assertEquals(STConnectType.RECT, type.getPathArray(0).getConnecttype());
 
         CTShape shape = vml.newCommentShape();
         assertEquals(3, items.size());
         assertSame(items.get(2),  shape);
-        assertEquals("#_xssf_cell_comment", shape.getType());
+        assertEquals("#_x0000_t202", shape.getType());
         assertEquals("position:absolute; visibility:hidden", shape.getStyle());
         assertEquals("#ffffe1", shape.getFillcolor());
         assertEquals(STInsetMode.AUTO, shape.getInsetmode());
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
index 209bded..392ab90 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
@@ -17,6 +17,7 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -25,6 +26,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -39,10 +41,11 @@
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
-
+import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.usermodel.BaseTestWorkbook;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
@@ -78,7 +81,8 @@
 	 */
 	@Test
 	public void saveLoadNew() throws Exception {
-		XSSFWorkbook workbook = new XSSFWorkbook();
+		@SuppressWarnings("resource")
+        XSSFWorkbook workbook = new XSSFWorkbook();
 
 		//check that the default date system is set to 1900
 		CTWorkbookPr pr = workbook.getCTWorkbook().getWorkbookPr();
@@ -121,7 +125,8 @@
 		// Links to the three sheets, shared strings and styles
 		assertTrue(wbPart.hasRelationships());
 		assertEquals(5, wbPart.getRelationships().size());
-
+		workbook.close();
+		
 		// Load back the XSSFWorkbook
 		workbook = new XSSFWorkbook(pkg);
 		assertEquals(3, workbook.getNumberOfSheets());
@@ -777,7 +782,7 @@
         Cell cell9 = row3.createCell(2);
         cell9.setCellValue("Bepa");
 
-        AreaReference source = new AreaReference("A1:B2");
+        AreaReference source = new AreaReference("A1:B2", SpreadsheetVersion.EXCEL2007);
         sheet.createPivotTable(source, new CellReference("H5"));
     }
 
@@ -869,4 +874,54 @@
             wb.close();
         }
     }
+
+    /**
+     * Tests that we can save a workbook with macros and reload it.
+     */
+    @Test
+    public void testSetVBAProject() throws Exception {
+        XSSFWorkbook workbook = null;
+        OutputStream out = null;
+        File file;
+        final byte[] allBytes = new byte[256];
+        for (int i = 0; i < 256; i++) {
+            allBytes[i] = (byte) (i - 128);
+        }
+        try {
+            workbook = new XSSFWorkbook();
+            workbook.createSheet();
+            workbook.setVBAProject(new ByteArrayInputStream(allBytes));
+            file = TempFile.createTempFile("poi-", ".xlsm");
+            out = new FileOutputStream(file);
+            workbook.write(out);
+        }
+        finally {
+            IOUtils.closeQuietly(out);
+            IOUtils.closeQuietly(workbook);
+        }
+
+        try {
+            // Check the package contains what we'd expect it to
+            OPCPackage pkg = OPCPackage.open(file.toString());
+            PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
+            assertTrue(wbPart.hasRelationships());
+            final PackageRelationshipCollection relationships = wbPart.getRelationships().getRelationships(XSSFRelation.VBA_MACROS.getRelation());
+            assertEquals(1, relationships.size());
+            assertEquals(XSSFRelation.VBA_MACROS.getDefaultFileName(), relationships.getRelationship(0).getTargetURI().toString());
+            PackagePart vbaPart = pkg.getPart(PackagingURIHelper.createPartName(XSSFRelation.VBA_MACROS.getDefaultFileName()));
+            assertNotNull(vbaPart);
+            assertFalse(vbaPart.isRelationshipPart());
+            assertEquals(XSSFRelation.VBA_MACROS.getContentType(), vbaPart.getContentType());
+            final byte[] fromFile = IOUtils.toByteArray(vbaPart.getInputStream());
+            assertArrayEquals(allBytes, fromFile);
+
+            // Load back the XSSFWorkbook just to check nothing explodes
+            workbook = new XSSFWorkbook(pkg);
+            assertEquals(1, workbook.getNumberOfSheets());
+            assertEquals(XSSFWorkbookType.XLSM, workbook.getWorkbookType());
+        }
+        finally {
+            IOUtils.closeQuietly(workbook);
+        }
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java b/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
index f7ed6df..7243f11 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
@@ -33,24 +33,24 @@
 
 /**
  * Collects all tests for <tt>org.apache.poi.xwpf</tt> and sub-packages.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    TestXWPFBugs.class,
-    org.apache.poi.xwpf.usermodel.TestXWPFBugs.class,
-    TestXWPFDocument.class,
-    TestXWPFWordExtractor.class,
-    TestXWPFHeaderFooterPolicy.class,
-    TestXWPFHeader.class,
-    TestXWPFHeadings.class,
-    TestXWPFParagraph.class,
-    TestXWPFRun.class,
-    TestXWPFTable.class,
-    TestXWPFStyles.class,
-    TestXWPFPictureData.class,
-    TestXWPFNumbering.class,
-    TestAllExtendedProperties.class,
-    TestPackageCorePropertiesGetKeywords.class
-})
-public final class AllXWPFTests {
+ */

+@RunWith(Suite.class)

+@Suite.SuiteClasses({

+        TestXWPFBugs.class,

+        org.apache.poi.xwpf.usermodel.TestXWPFBugs.class,

+        TestXWPFDocument.class,

+        TestXWPFWordExtractor.class,

+        TestXWPFHeaderFooterPolicy.class,

+        TestXWPFHeader.class,

+        TestXWPFHeadings.class,

+        TestXWPFParagraph.class,

+        TestXWPFRun.class,

+        TestXWPFTable.class,

+        TestXWPFStyles.class,

+        TestXWPFPictureData.class,

+        TestXWPFNumbering.class,

+        TestAllExtendedProperties.class,

+        TestPackageCorePropertiesGetKeywords.class

+})

+public final class AllXWPFTests {

 }
\ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java
index c04f73c..ff955da 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/TestAllExtendedProperties.java
@@ -17,13 +17,12 @@
 
 package org.apache.poi.xwpf;
 
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.POIXMLProperties.CoreProperties;
-import org.apache.poi.openxml4j.opc.PackageProperties;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.POIXMLProperties.CoreProperties;

+import org.apache.poi.openxml4j.opc.PackageProperties;

+import org.apache.poi.xwpf.usermodel.XWPFDocument;

 import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTDigSigBlob;
 import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties;
 import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTVectorLpstr;
@@ -31,77 +30,76 @@
 
 /**
  * Tests if the {@link CoreProperties#getKeywords()} method. This test has been
- * submitted because even though the
- * {@link PackageProperties#getKeywordsProperty()} had been present before, the
- * {@link CoreProperties#getKeywords()} had been missing.
- * 
- * The author of this has added {@link CoreProperties#getKeywords()} and
- * {@link CoreProperties#setKeywords(String)} and this test is supposed to test
- * them.
- * 
- * @author Antoni Mylka
- * 
- */
-public final class TestAllExtendedProperties extends TestCase {
-	public void testGetAllExtendedProperties() throws IOException {
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");
-		CTProperties ctProps = doc.getProperties().getExtendedProperties().getUnderlyingProperties();
-		assertEquals("Microsoft Office Word",ctProps.getApplication());
-		assertEquals("14.0000",ctProps.getAppVersion());
-		assertEquals(57,ctProps.getCharacters());
-		assertEquals(66,ctProps.getCharactersWithSpaces());
-		assertEquals("",ctProps.getCompany());
-		assertNull(ctProps.getDigSig());
-		assertEquals(0,ctProps.getDocSecurity());
-		assertNotNull(ctProps.getDomNode());
-		
-		CTVectorVariant vec = ctProps.getHeadingPairs();
-		assertEquals(2,vec.getVector().sizeOfVariantArray());
-		assertEquals("Title",vec.getVector().getVariantArray(0).getLpstr());
-		assertEquals(1,vec.getVector().getVariantArray(1).getI4());
-		
-		assertFalse(ctProps.isSetHiddenSlides());
-		assertEquals(0,ctProps.getHiddenSlides());
-		assertFalse(ctProps.isSetHLinks());
-		assertNull(ctProps.getHLinks());
-		assertNull(ctProps.getHyperlinkBase());
-		assertTrue(ctProps.isSetHyperlinksChanged());
-		assertFalse(ctProps.getHyperlinksChanged());
-		assertEquals(1,ctProps.getLines());
-		assertTrue(ctProps.isSetLinksUpToDate());
-		assertFalse(ctProps.getLinksUpToDate());
-		assertNull(ctProps.getManager());
-		assertFalse(ctProps.isSetMMClips());
-		assertEquals(0,ctProps.getMMClips());
-		assertFalse(ctProps.isSetNotes());
-		assertEquals(0,ctProps.getNotes());
-		assertEquals(1,ctProps.getPages());
-		assertEquals(1,ctProps.getParagraphs());
-		assertNull(ctProps.getPresentationFormat());
-		assertTrue(ctProps.isSetScaleCrop());
-		assertFalse(ctProps.getScaleCrop());
-		assertTrue(ctProps.isSetSharedDoc());
-		assertFalse(ctProps.getSharedDoc());
-		assertFalse(ctProps.isSetSlides());
-		assertEquals(0,ctProps.getSlides());
-		assertEquals("Normal.dotm",ctProps.getTemplate());
-		
-		CTVectorLpstr vec2 = ctProps.getTitlesOfParts();
-		assertEquals(1,vec2.getVector().sizeOfLpstrArray());
-		assertEquals("Example Word 2010 Document",vec2.getVector().getLpstrArray(0));
-		
-		assertEquals(3,ctProps.getTotalTime());
-		assertEquals(10,ctProps.getWords());
-		
-		// Check the digital signature part
-		// Won't be there in this file, but we
-		//  need to do this check so that the
-		//  appropriate parts end up in the
-		//  smaller ooxml schemas file
-		CTDigSigBlob blob = ctProps.getDigSig();
-		assertNull(blob);
-		
-		blob = CTDigSigBlob.Factory.newInstance();
-		blob.setBlob(new byte [] {2,6,7,2,3,4,5,1,2,3});
-	}
-}
+ * submitted because even though the

+ * {@link PackageProperties#getKeywordsProperty()} had been present before, the

+ * {@link CoreProperties#getKeywords()} had been missing.

+ * <p/>

+ * The author of this has added {@link CoreProperties#getKeywords()} and

+ * {@link CoreProperties#setKeywords(String)} and this test is supposed to test

+ * them.

+ *

+ * @author Antoni Mylka

+ */

+public final class TestAllExtendedProperties extends TestCase {

+    public void testGetAllExtendedProperties() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");

+        CTProperties ctProps = doc.getProperties().getExtendedProperties().getUnderlyingProperties();

+        assertEquals("Microsoft Office Word", ctProps.getApplication());

+        assertEquals("14.0000", ctProps.getAppVersion());

+        assertEquals(57, ctProps.getCharacters());

+        assertEquals(66, ctProps.getCharactersWithSpaces());

+        assertEquals("", ctProps.getCompany());

+        assertNull(ctProps.getDigSig());

+        assertEquals(0, ctProps.getDocSecurity());

+        assertNotNull(ctProps.getDomNode());

+

+        CTVectorVariant vec = ctProps.getHeadingPairs();

+        assertEquals(2, vec.getVector().sizeOfVariantArray());

+        assertEquals("Title", vec.getVector().getVariantArray(0).getLpstr());

+        assertEquals(1, vec.getVector().getVariantArray(1).getI4());

+

+        assertFalse(ctProps.isSetHiddenSlides());

+        assertEquals(0, ctProps.getHiddenSlides());

+        assertFalse(ctProps.isSetHLinks());

+        assertNull(ctProps.getHLinks());

+        assertNull(ctProps.getHyperlinkBase());

+        assertTrue(ctProps.isSetHyperlinksChanged());

+        assertFalse(ctProps.getHyperlinksChanged());

+        assertEquals(1, ctProps.getLines());

+        assertTrue(ctProps.isSetLinksUpToDate());

+        assertFalse(ctProps.getLinksUpToDate());

+        assertNull(ctProps.getManager());

+        assertFalse(ctProps.isSetMMClips());

+        assertEquals(0, ctProps.getMMClips());

+        assertFalse(ctProps.isSetNotes());

+        assertEquals(0, ctProps.getNotes());

+        assertEquals(1, ctProps.getPages());

+        assertEquals(1, ctProps.getParagraphs());

+        assertNull(ctProps.getPresentationFormat());

+        assertTrue(ctProps.isSetScaleCrop());

+        assertFalse(ctProps.getScaleCrop());

+        assertTrue(ctProps.isSetSharedDoc());

+        assertFalse(ctProps.getSharedDoc());

+        assertFalse(ctProps.isSetSlides());

+        assertEquals(0, ctProps.getSlides());

+        assertEquals("Normal.dotm", ctProps.getTemplate());

+

+        CTVectorLpstr vec2 = ctProps.getTitlesOfParts();

+        assertEquals(1, vec2.getVector().sizeOfLpstrArray());

+        assertEquals("Example Word 2010 Document", vec2.getVector().getLpstrArray(0));

+

+        assertEquals(3, ctProps.getTotalTime());

+        assertEquals(10, ctProps.getWords());

+

+        // Check the digital signature part

+        // Won't be there in this file, but we

+        //  need to do this check so that the

+        //  appropriate parts end up in the

+        //  smaller ooxml schemas file

+        CTDigSigBlob blob = ctProps.getDigSig();

+        assertNull(blob);

+

+        blob = CTDigSigBlob.Factory.newInstance();

+        blob.setBlob(new byte[]{2, 6, 7, 2, 3, 4, 5, 1, 2, 3});

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java
index 4b37623..85a21f1 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/TestPackageCorePropertiesGetKeywords.java
@@ -17,36 +17,34 @@
 
 package org.apache.poi.xwpf;
 
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.POIXMLProperties.CoreProperties;
-import org.apache.poi.openxml4j.opc.PackageProperties;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.POIXMLProperties.CoreProperties;

+import org.apache.poi.openxml4j.opc.PackageProperties;

+import org.apache.poi.xwpf.usermodel.XWPFDocument;

 
 /**
  * Tests if the {@link CoreProperties#getKeywords()} method. This test has been
- * submitted because even though the
- * {@link PackageProperties#getKeywordsProperty()} had been present before, the
- * {@link CoreProperties#getKeywords()} had been missing.
- * 
- * The author of this has added {@link CoreProperties#getKeywords()} and
- * {@link CoreProperties#setKeywords(String)} and this test is supposed to test
- * them.
- * 
- * @author Antoni Mylka
- * 
- */
-public final class TestPackageCorePropertiesGetKeywords extends TestCase {
-	public void testGetSetKeywords() throws IOException {
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");
-		String keywords = doc.getProperties().getCoreProperties().getKeywords();
-		assertEquals("extractor, test, rdf", keywords);
-		
-		doc.getProperties().getCoreProperties().setKeywords("test, keywords");
-		doc = XWPFTestDataSamples.writeOutAndReadBack(doc);
-		keywords = doc.getProperties().getCoreProperties().getKeywords();
-		assertEquals("test, keywords",keywords);
-	}
-}
+ * submitted because even though the

+ * {@link PackageProperties#getKeywordsProperty()} had been present before, the

+ * {@link CoreProperties#getKeywords()} had been missing.

+ * <p/>

+ * The author of this has added {@link CoreProperties#getKeywords()} and

+ * {@link CoreProperties#setKeywords(String)} and this test is supposed to test

+ * them.

+ *

+ * @author Antoni Mylka

+ */

+public final class TestPackageCorePropertiesGetKeywords extends TestCase {

+    public void testGetSetKeywords() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");

+        String keywords = doc.getProperties().getCoreProperties().getKeywords();

+        assertEquals("extractor, test, rdf", keywords);

+

+        doc.getProperties().getCoreProperties().setKeywords("test, keywords");

+        doc = XWPFTestDataSamples.writeOutAndReadBack(doc);

+        keywords = doc.getProperties().getCoreProperties().getKeywords();

+        assertEquals("test, keywords", keywords);

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java
index 055e470..6f7e4b6 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java
@@ -40,7 +40,7 @@
 public class TestXWPFBugs {

     /**

      * A word document that's encrypted with non-standard

-     *  Encryption options, and no cspname section. See bug 53475

+     * Encryption options, and no cspname section. See bug 53475

      */

     @Test

     public void bug53475NoCSPName() throws Exception {

@@ -54,7 +54,7 @@
         assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx());

 

         // Check it can be decoded

-        Decryptor d = Decryptor.getInstance(info);		

+        Decryptor d = Decryptor.getInstance(info);

         assertTrue("Unable to process: document is encrypted", d.verifyPassword("solrcell"));

 

         // Check we can read the word document in that

@@ -66,7 +66,7 @@
         assertNotNull(text);

         assertEquals("This is password protected Word document.", text.trim());

         ex.close();

-        

+

         filesystem.close();

     }

 

@@ -90,7 +90,7 @@
         assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx());

 

         // Check it can be decoded

-        Decryptor d = Decryptor.getInstance(info);		

+        Decryptor d = Decryptor.getInstance(info);

         assertTrue("Unable to process: document is encrypted", d.verifyPassword("pass"));

 

         // Check we can read the word document in that

@@ -103,7 +103,7 @@
         // I know ... a stupid typo, maybe next time ...

         assertEquals("The is a password protected document.", text.trim());

         ex.close();

-        

+

         filesystem.close();

     }

 }

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java
index 05d6b2f..929d430 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestExternalEntities.java
@@ -20,7 +20,6 @@
 import java.io.IOException;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 
@@ -28,19 +27,20 @@
 
     /**
      * Get text out of the simple file
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void testFile() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ExternalEntityInText.docx");
         XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
 
         String text = extractor.getText();
-        
+
         assertTrue(text.length() > 0);
 
         // Check contents, they should not contain the text from POI web site after colon!
         assertEquals("Here should not be the POI web site: \"\"", text.trim());
-        
+
         extractor.close();
     }
 
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
index 0040882..48330bb 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
@@ -22,7 +22,6 @@
 import java.util.regex.Pattern;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 
@@ -33,7 +32,8 @@
 
     /**
      * Get text out of the simple file
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void testGetSimpleText() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
@@ -59,13 +59,14 @@
             }
         }
         assertEquals(3, ps);
-        
+
         extractor.close();
     }
 
     /**
      * Tests getting the text out of a complex file
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void testGetComplexText() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
@@ -97,7 +98,7 @@
             }
         }
         assertEquals(134, ps);
-        
+
         extractor.close();
     }
 
@@ -108,23 +109,23 @@
         // Now check contents
         extractor.setFetchHyperlinks(false);
         assertEquals(
-				"This is a test document.\nThis bit is in bold and italic\n" +
-				"Back to normal\n" +
-				"This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" +
-				"We have a hyperlink here, and another.\n",
+                "This is a test document.\nThis bit is in bold and italic\n" +
+                        "Back to normal\n" +
+                        "This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" +
+                        "We have a hyperlink here, and another.\n",
                 extractor.getText()
         );
 
         // One hyperlink is a real one, one is just to the top of page
         extractor.setFetchHyperlinks(true);
         assertEquals(
-				"This is a test document.\nThis bit is in bold and italic\n" +
-				"Back to normal\n" +
-				"This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" +
-				"We have a hyperlink <http://poi.apache.org/> here, and another.\n",
+                "This is a test document.\nThis bit is in bold and italic\n" +
+                        "Back to normal\n" +
+                        "This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.\n" +
+                        "We have a hyperlink <http://poi.apache.org/> here, and another.\n",
                 extractor.getText()
         );
-        
+
         extractor.close();
     }
 
@@ -173,7 +174,7 @@
                         "Footer Left\tFooter Middle\tFooter Right\n",
                 extractor.getText()
         );
-        
+
         extractor.close();
     }
 
@@ -183,7 +184,7 @@
         String text = extractor.getText();
         assertTrue(text.contains("snoska"));
         assertTrue(text.contains("Eto ochen prostoy[footnoteRef:1] text so snoskoy"));
-        
+
         extractor.close();
     }
 
@@ -193,7 +194,7 @@
         XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
 
         assertTrue(extractor.getText().contains("snoska"));
-        
+
         extractor.close();
     }
 
@@ -204,7 +205,7 @@
         String text = extractor.getText();
         assertTrue("Unable to find expected word in text\n" + text, text.contains("testdoc"));
         assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase"));
-        
+
         extractor.close();
     }
 
@@ -214,7 +215,7 @@
         String text = extractor.getText();
         assertTrue(text.contains("XXX"));
         assertTrue(text.contains("tilaka [endnoteRef:2]or 'tika'"));
-        
+
         extractor.close();
     }
 
@@ -224,7 +225,7 @@
 
         assertTrue(extractor.getText().contains("pendant worn"));
         assertTrue(extractor.getText().contains("extremely well"));
-        
+
         extractor.close();
     }
 
@@ -235,14 +236,15 @@
         assertTrue(extractor.getText().contains("Section 1"));
         assertTrue(extractor.getText().contains("Section 2"));
         assertTrue(extractor.getText().contains("Section 3"));
-        
+
         extractor.close();
     }
 
     /**
      * Test that we can open and process .docm
-     *  (macro enabled) docx files (bug #45690)
-     * @throws IOException 
+     * (macro enabled) docx files (bug #45690)
+     *
+     * @throws IOException
      */
     public void testDOCMFiles() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("45690.docm");
@@ -251,35 +253,37 @@
         assertTrue(extractor.getText().contains("2004"));
         assertTrue(extractor.getText().contains("2008"));
         assertTrue(extractor.getText().contains("(120 "));
-        
+
         extractor.close();
     }
-    
+
     /**
      * Test that we handle things like tabs and
-     *  carriage returns properly in the text that
-     *  we're extracting (bug #49189)
-     * @throws IOException 
+     * carriage returns properly in the text that
+     * we're extracting (bug #49189)
+     *
+     * @throws IOException
      */
     public void testDocTabs() throws IOException {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithTabs.docx");
-       XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
- 
-       // Check bits
-       assertTrue(extractor.getText().contains("a"));
-       assertTrue(extractor.getText().contains("\t"));
-       assertTrue(extractor.getText().contains("b"));
-       
-       // Now check the first paragraph in total
-       assertTrue(extractor.getText().contains("a\tb\n"));
-       
-       extractor.close();
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithTabs.docx");
+        XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
+
+        // Check bits
+        assertTrue(extractor.getText().contains("a"));
+        assertTrue(extractor.getText().contains("\t"));
+        assertTrue(extractor.getText().contains("b"));
+
+        // Now check the first paragraph in total
+        assertTrue(extractor.getText().contains("a\tb\n"));
+
+        extractor.close();
     }
-    
+
     /**
      * The output should not contain field codes, e.g. those specified in the
      * w:instrText tag (spec sec. 17.16.23)
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void testNoFieldCodes() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FieldCodes.docx");
@@ -288,14 +292,15 @@
         assertTrue(text.length() > 0);
         assertFalse(text.contains("AUTHOR"));
         assertFalse(text.contains("CREATEDATE"));
-        
+
         extractor.close();
     }
-    
+
     /**
      * The output should contain the values of simple fields, those specified
      * with the fldSimple element (spec sec. 17.16.19)
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void testFldSimpleContent() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FldSimple.docx");
@@ -303,7 +308,7 @@
         String text = extractor.getText();
         assertTrue(text.length() > 0);
         assertTrue(text.contains("FldSimple.docx"));
-        
+
         extractor.close();
     }
 
@@ -316,12 +321,13 @@
         XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
         String text = extractor.getText();
         assertTrue(text.length() > 0);
-        
+
         extractor.close();
     }
-    
+
     /**
      * Test for basic extraction of SDT content
+     *
      * @throws IOException
      */
     public void testSimpleControlContent() throws IOException {
@@ -345,19 +351,19 @@
         XWPFWordExtractor ex = new XWPFWordExtractor(doc);
         String s = ex.getText().toLowerCase();
         int hits = 0;
-    
-        for (String targ : targs){
+
+        for (String targ : targs) {
             boolean hit = false;
-            if (s.indexOf(targ) > -1){
+            if (s.indexOf(targ) > -1) {
                 hit = true;
                 hits++;
             }
-            assertEquals("controlled content loading-"+targ, true, hit);
+            assertEquals("controlled content loading-" + targ, true, hit);
         }
         assertEquals("controlled content loading hit count", targs.length, hits);
         ex.close();
-        
-        
+
+
         doc = XWPFTestDataSamples.openSampleDocument("Bug54771a.docx");
         targs = new String[]{
                 "bb",
@@ -366,48 +372,50 @@
         };
         ex = new XWPFWordExtractor(doc);
         s = ex.getText().toLowerCase();
-        
+
         //At one point in development there were three copies of the text.
         //This ensures that there is only one copy.
-        for (String targ : targs){
+        for (String targ : targs) {
             Matcher m = Pattern.compile(targ).matcher(s);
             int hit = 0;
             while (m.find()) {
                 hit++;
             }
-            assertEquals("controlled content loading-"+targ, 1, hit);
+            assertEquals("controlled content loading-" + targ, 1, hit);
         }
         //"test\n" appears twice: once as the "title" and once in the text.
         //This also happens when you save this document as text from MSWord.
         Matcher m = Pattern.compile("test\n").matcher(s);
         int hit = 0;
-        while (m.find()){
+        while (m.find()) {
             hit++;
         }
         assertEquals("test<N>", 2, hit);
         ex.close();
     }
 
-    /** No Header or Footer in document */
+    /**
+     * No Header or Footer in document
+     */
     public void testBug55733() throws Exception {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("55733.docx");
-    	XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
+        XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
 
         // Check it gives text without error
         extractor.getText();
         extractor.close();
     }
-    
-    public void testCheckboxes() throws IOException  {
+
+    public void testCheckboxes() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("checkboxes.docx");
         System.out.println(doc);
         XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
-        
+
         assertEquals("This is a small test for checkboxes \nunchecked: |_| \n" +
-                     "Or checked: |X|\n\n\n\n\n" +
-                     "Test a checkbox within a textbox: |_| -> |X|\n\n\n" +
-                     "In Table:\n|_|\t|X|\n\n\n" +
-                     "In Sequence:\n|X||_||X|\n", extractor.getText());
+                "Or checked: |X|\n\n\n\n\n" +
+                "Test a checkbox within a textbox: |_| -> |X|\n\n\n" +
+                "In Table:\n|_|\t|X|\n\n\n" +
+                "In Sequence:\n|X||_||X|\n", extractor.getText());
         extractor.close();
     }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java b/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java
index 3df111b..aa1167d 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFDecorators.java
@@ -17,86 +17,85 @@
 
 package org.apache.poi.xwpf.model;
 
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
-import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun;
+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.apache.poi.xwpf.usermodel.XWPFDocument;

+import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun;

 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 
 /**
- * Tests for the various XWPF decorators
- */
-public class TestXWPFDecorators extends TestCase {
-   private XWPFDocument simple;
-   private XWPFDocument hyperlink;
-   private XWPFDocument comments;
-
-   protected void setUp() throws IOException {
-        simple = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
-        hyperlink = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
-        comments = XWPFTestDataSamples.openSampleDocument("WordWithAttachments.docx");
-   }
-
-    @SuppressWarnings("deprecation")
-   public void testHyperlink() {
-      XWPFParagraph ps;
-      XWPFParagraph ph;
-      assertEquals(7, simple.getParagraphs().size());
-      assertEquals(5, hyperlink.getParagraphs().size());
-
-      // Simple text
-      ps = simple.getParagraphs().get(0);
-      assertEquals("I am a test document", ps.getParagraphText());
-      assertEquals(1, ps.getRuns().size());
-
-      ph = hyperlink.getParagraphs().get(4);
-      assertEquals("We have a hyperlink here, and another.", ph.getParagraphText());
-      assertEquals(3, ph.getRuns().size());
-
-
-      // The proper way to do hyperlinks(!)
-      assertFalse(ps.getRuns().get(0) instanceof XWPFHyperlinkRun);
-      assertFalse(ph.getRuns().get(0) instanceof XWPFHyperlinkRun);
-      assertTrue(ph.getRuns().get(1) instanceof XWPFHyperlinkRun);
-      assertFalse(ph.getRuns().get(2) instanceof XWPFHyperlinkRun);
-
-      XWPFHyperlinkRun link = (XWPFHyperlinkRun)ph.getRuns().get(1);
-      assertEquals("http://poi.apache.org/", link.getHyperlink(hyperlink).getURL());
-
-
-      // Test the old style decorator
-      // You probably don't want to still be using it...
-      assertEquals(
-            "I am a test document",
-            (new XWPFHyperlinkDecorator(ps, null, false)).getText()
-      );
-      assertEquals(
-            "I am a test document",
-            (new XWPFHyperlinkDecorator(ps, null, true)).getText()
-      );
-
-      assertEquals(
-            "We have a hyperlink here, and another.hyperlink",
-            (new XWPFHyperlinkDecorator(ph, null, false)).getText()
-      );
-      assertEquals(
-            "We have a hyperlink here, and another.hyperlink <http://poi.apache.org/>",
-            (new XWPFHyperlinkDecorator(ph, null, true)).getText()
-      );
-   }
-
-   public void testComments() {
-      int numComments = 0;
-      for(XWPFParagraph p : comments.getParagraphs()) {
-         XWPFCommentsDecorator d = new XWPFCommentsDecorator(p, null);
-         if(d.getCommentText().length() > 0) {
-            numComments++;
-            assertEquals("\tComment by", d.getCommentText().substring(0, 11));
-         }
-      }
-      assertEquals(3, numComments);
-   }
-}
+ * Tests for the various XWPF decorators

+ */

+public class TestXWPFDecorators extends TestCase {

+    private XWPFDocument simple;

+    private XWPFDocument hyperlink;

+    private XWPFDocument comments;

+

+    protected void setUp() throws IOException {

+        simple = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");

+        hyperlink = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");

+        comments = XWPFTestDataSamples.openSampleDocument("WordWithAttachments.docx");

+    }

+

+    @SuppressWarnings("deprecation")

+    public void testHyperlink() {

+        XWPFParagraph ps;

+        XWPFParagraph ph;

+        assertEquals(7, simple.getParagraphs().size());

+        assertEquals(5, hyperlink.getParagraphs().size());

+

+        // Simple text

+        ps = simple.getParagraphs().get(0);

+        assertEquals("I am a test document", ps.getParagraphText());

+        assertEquals(1, ps.getRuns().size());

+

+        ph = hyperlink.getParagraphs().get(4);

+        assertEquals("We have a hyperlink here, and another.", ph.getParagraphText());

+        assertEquals(3, ph.getRuns().size());

+

+

+        // The proper way to do hyperlinks(!)

+        assertFalse(ps.getRuns().get(0) instanceof XWPFHyperlinkRun);

+        assertFalse(ph.getRuns().get(0) instanceof XWPFHyperlinkRun);

+        assertTrue(ph.getRuns().get(1) instanceof XWPFHyperlinkRun);

+        assertFalse(ph.getRuns().get(2) instanceof XWPFHyperlinkRun);

+

+        XWPFHyperlinkRun link = (XWPFHyperlinkRun) ph.getRuns().get(1);

+        assertEquals("http://poi.apache.org/", link.getHyperlink(hyperlink).getURL());

+

+

+        // Test the old style decorator

+        // You probably don't want to still be using it...

+        assertEquals(

+                "I am a test document",

+                (new XWPFHyperlinkDecorator(ps, null, false)).getText()

+        );

+        assertEquals(

+                "I am a test document",

+                (new XWPFHyperlinkDecorator(ps, null, true)).getText()

+        );

+

+        assertEquals(

+                "We have a hyperlink here, and another.hyperlink",

+                (new XWPFHyperlinkDecorator(ph, null, false)).getText()

+        );

+        assertEquals(

+                "We have a hyperlink here, and another.hyperlink <http://poi.apache.org/>",

+                (new XWPFHyperlinkDecorator(ph, null, true)).getText()

+        );

+    }

+

+    public void testComments() {

+        int numComments = 0;

+        for (XWPFParagraph p : comments.getParagraphs()) {

+            XWPFCommentsDecorator d = new XWPFCommentsDecorator(p, null);

+            if (d.getCommentText().length() > 0) {

+                numComments++;

+                assertEquals("\tComment by", d.getCommentText().substring(0, 11));

+            }

+        }

+        assertEquals(3, numComments);

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java b/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java
index 7d70866..d461265 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/model/TestXWPFHeaderFooterPolicy.java
@@ -20,7 +20,6 @@
 import java.io.IOException;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 
@@ -28,130 +27,130 @@
  * Tests for XWPF Header Footer Stuff
  */
 public class TestXWPFHeaderFooterPolicy extends TestCase {
-	private XWPFDocument noHeader;
-	private XWPFDocument header;
-	private XWPFDocument headerFooter;
-	private XWPFDocument footer;
-	private XWPFDocument oddEven;
-	private XWPFDocument diffFirst;
+    private XWPFDocument noHeader;
+    private XWPFDocument header;
+    private XWPFDocument headerFooter;
+    private XWPFDocument footer;
+    private XWPFDocument oddEven;
+    private XWPFDocument diffFirst;
 
-	protected void setUp() throws IOException {
+    protected void setUp() throws IOException {
 
-	    noHeader = XWPFTestDataSamples.openSampleDocument("NoHeadFoot.docx");
-		header = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
-		headerFooter = XWPFTestDataSamples.openSampleDocument("SimpleHeadThreeColFoot.docx");
-		footer = XWPFTestDataSamples.openSampleDocument("FancyFoot.docx");
-		oddEven = XWPFTestDataSamples.openSampleDocument("PageSpecificHeadFoot.docx");
-		diffFirst = XWPFTestDataSamples.openSampleDocument("DiffFirstPageHeadFoot.docx");
-	}
+        noHeader = XWPFTestDataSamples.openSampleDocument("NoHeadFoot.docx");
+        header = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
+        headerFooter = XWPFTestDataSamples.openSampleDocument("SimpleHeadThreeColFoot.docx");
+        footer = XWPFTestDataSamples.openSampleDocument("FancyFoot.docx");
+        oddEven = XWPFTestDataSamples.openSampleDocument("PageSpecificHeadFoot.docx");
+        diffFirst = XWPFTestDataSamples.openSampleDocument("DiffFirstPageHeadFoot.docx");
+    }
 
-	public void testPolicy() {
-		XWPFHeaderFooterPolicy policy;
+    public void testPolicy() {
+        XWPFHeaderFooterPolicy policy;
 
-		policy = noHeader.getHeaderFooterPolicy();
-		assertNull(policy.getDefaultHeader());
-		assertNull(policy.getDefaultFooter());
+        policy = noHeader.getHeaderFooterPolicy();
+        assertNull(policy.getDefaultHeader());
+        assertNull(policy.getDefaultFooter());
 
-		assertNull(policy.getHeader(1));
-		assertNull(policy.getHeader(2));
-		assertNull(policy.getHeader(3));
-		assertNull(policy.getFooter(1));
-		assertNull(policy.getFooter(2));
-		assertNull(policy.getFooter(3));
+        assertNull(policy.getHeader(1));
+        assertNull(policy.getHeader(2));
+        assertNull(policy.getHeader(3));
+        assertNull(policy.getFooter(1));
+        assertNull(policy.getFooter(2));
+        assertNull(policy.getFooter(3));
 
 
-		policy = header.getHeaderFooterPolicy();
-		assertNotNull(policy.getDefaultHeader());
-		assertNull(policy.getDefaultFooter());
+        policy = header.getHeaderFooterPolicy();
+        assertNotNull(policy.getDefaultHeader());
+        assertNull(policy.getDefaultFooter());
 
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
-		assertNull(policy.getFooter(1));
-		assertNull(policy.getFooter(2));
-		assertNull(policy.getFooter(3));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
+        assertNull(policy.getFooter(1));
+        assertNull(policy.getFooter(2));
+        assertNull(policy.getFooter(3));
 
 
-		policy = footer.getHeaderFooterPolicy();
-		assertNull(policy.getDefaultHeader());
-		assertNotNull(policy.getDefaultFooter());
+        policy = footer.getHeaderFooterPolicy();
+        assertNull(policy.getDefaultHeader());
+        assertNotNull(policy.getDefaultFooter());
 
-		assertNull(policy.getHeader(1));
-		assertNull(policy.getHeader(2));
-		assertNull(policy.getHeader(3));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
+        assertNull(policy.getHeader(1));
+        assertNull(policy.getHeader(2));
+        assertNull(policy.getHeader(3));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
 
 
-		policy = headerFooter.getHeaderFooterPolicy();
-		assertNotNull(policy.getDefaultHeader());
-		assertNotNull(policy.getDefaultFooter());
+        policy = headerFooter.getHeaderFooterPolicy();
+        assertNotNull(policy.getDefaultHeader());
+        assertNotNull(policy.getDefaultFooter());
 
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
 
 
-		policy = oddEven.getHeaderFooterPolicy();
-		assertNotNull(policy.getDefaultHeader());
-		assertNotNull(policy.getDefaultFooter());
-		assertNotNull(policy.getEvenPageHeader());
-		assertNotNull(policy.getEvenPageFooter());
+        policy = oddEven.getHeaderFooterPolicy();
+        assertNotNull(policy.getDefaultHeader());
+        assertNotNull(policy.getDefaultFooter());
+        assertNotNull(policy.getEvenPageHeader());
+        assertNotNull(policy.getEvenPageFooter());
 
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
-		assertEquals(policy.getEvenPageHeader(), policy.getHeader(2));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
-		assertEquals(policy.getEvenPageFooter(), policy.getFooter(2));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(1));
+        assertEquals(policy.getEvenPageHeader(), policy.getHeader(2));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(1));
+        assertEquals(policy.getEvenPageFooter(), policy.getFooter(2));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
 
 
-		policy = diffFirst.getHeaderFooterPolicy();
-		assertNotNull(policy.getDefaultHeader());
-		assertNotNull(policy.getDefaultFooter());
-		assertNotNull(policy.getFirstPageHeader());
-		assertNotNull(policy.getFirstPageFooter());
-		assertNull(policy.getEvenPageHeader());
-		assertNull(policy.getEvenPageFooter());
+        policy = diffFirst.getHeaderFooterPolicy();
+        assertNotNull(policy.getDefaultHeader());
+        assertNotNull(policy.getDefaultFooter());
+        assertNotNull(policy.getFirstPageHeader());
+        assertNotNull(policy.getFirstPageFooter());
+        assertNull(policy.getEvenPageHeader());
+        assertNull(policy.getEvenPageFooter());
 
-		assertEquals(policy.getFirstPageHeader(), policy.getHeader(1));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
-		assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
-		assertEquals(policy.getFirstPageFooter(), policy.getFooter(1));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
-		assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
-	}
+        assertEquals(policy.getFirstPageHeader(), policy.getHeader(1));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(2));
+        assertEquals(policy.getDefaultHeader(), policy.getHeader(3));
+        assertEquals(policy.getFirstPageFooter(), policy.getFooter(1));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(2));
+        assertEquals(policy.getDefaultFooter(), policy.getFooter(3));
+    }
 
-	public void testContents() {
-		XWPFHeaderFooterPolicy policy;
+    public void testContents() {
+        XWPFHeaderFooterPolicy policy;
 
-		// Test a few simple bits off a simple header
-		policy = diffFirst.getHeaderFooterPolicy();
+        // Test a few simple bits off a simple header
+        policy = diffFirst.getHeaderFooterPolicy();
 
-		assertEquals(
-			"I am the header on the first page, and I" + '\u2019' + "m nice and simple\n",
-			policy.getFirstPageHeader().getText()
-		);
-		assertEquals(
-				"First header column!\tMid header\tRight header!\n",
-				policy.getDefaultHeader().getText()
-		);
+        assertEquals(
+                "I am the header on the first page, and I" + '\u2019' + "m nice and simple\n",
+                policy.getFirstPageHeader().getText()
+        );
+        assertEquals(
+                "First header column!\tMid header\tRight header!\n",
+                policy.getDefaultHeader().getText()
+        );
 
 
-		// And a few bits off a more complex header
-		policy = oddEven.getHeaderFooterPolicy();
+        // And a few bits off a more complex header
+        policy = oddEven.getHeaderFooterPolicy();
 
-		assertEquals(
-			"[ODD Page Header text]\n\n",
-			policy.getDefaultHeader().getText()
-		);
-		assertEquals(
-			"[This is an Even Page, with a Header]\n\n",
-			policy.getEvenPageHeader().getText()
-		);
-	}
+        assertEquals(
+                "[ODD Page Header text]\n\n",
+                policy.getDefaultHeader().getText()
+        );
+        assertEquals(
+                "[This is an Even Page, with a Header]\n\n",
+                policy.getEvenPageHeader().getText()
+        );
+    }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java
index d3e4758..0a309a8 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestChangeTracking.java
@@ -44,7 +44,7 @@
         assertFalse(document.isTrackRevisions());

 

         document.setTrackRevisions(true);

-        

+

         assertTrue(document.isTrackRevisions());

     }

 

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java
index bded4e4..78df19c 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java
@@ -16,10 +16,12 @@
 ==================================================================== */

 package org.apache.poi.xwpf.usermodel;

 

-import static org.junit.Assert.*;

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotNull;

 

 import java.io.IOException;

 

+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;

 import org.apache.poi.xwpf.XWPFTestDataSamples;

 import org.apache.poi.xwpf.usermodel.XWPFRun.FontCharRange;

 import org.junit.Test;

@@ -28,14 +30,14 @@
     @Test

     public void bug55802() throws Exception {

         String blabla =

-            "Bir, iki, \u00fc\u00e7, d\u00f6rt, be\u015f,\n"+

-            "\nalt\u0131, yedi, sekiz, dokuz, on.\n"+

-            "\nK\u0131rm\u0131z\u0131 don,\n"+

-            "\ngel bizim bah\u00e7eye kon,\n"+

-            "\nsar\u0131 limon";

+                "Bir, iki, \u00fc\u00e7, d\u00f6rt, be\u015f,\n" +

+                        "\nalt\u0131, yedi, sekiz, dokuz, on.\n" +

+                        "\nK\u0131rm\u0131z\u0131 don,\n" +

+                        "\ngel bizim bah\u00e7eye kon,\n" +

+                        "\nsar\u0131 limon";

         XWPFDocument doc = new XWPFDocument();

         XWPFRun run = doc.createParagraph().createRun();

-        

+

         for (String str : blabla.split("\n")) {

             run.setText(str);

             run.addBreak();

@@ -51,30 +53,52 @@
         assertEquals(run.getFontFamily(FontCharRange.hAnsi), "Arial");

     }

 

-    

+

     @Test

     public void bug57312_NullPointException() throws IOException {

         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("57312.docx");

         assertNotNull(doc);

-        

-        for( IBodyElement bodyElement : doc.getBodyElements()){

+

+        for (IBodyElement bodyElement : doc.getBodyElements()) {

             BodyElementType elementType = bodyElement.getElementType();

-            

-            if(elementType == BodyElementType.PARAGRAPH) {

+

+            if (elementType == BodyElementType.PARAGRAPH) {

                 XWPFParagraph paragraph = (XWPFParagraph) bodyElement;

-                

-                for (IRunElement iRunElem : paragraph.getIRuns()){

-                    

-                    if (iRunElem instanceof XWPFRun){   

+

+                for (IRunElement iRunElem : paragraph.getIRuns()) {

+

+                    if (iRunElem instanceof XWPFRun) {

                         XWPFRun runElement = (XWPFRun) iRunElem;

-                        

+

                         UnderlinePatterns underline = runElement.getUnderline();

                         assertNotNull(underline);

-                        

+

                         //System.out.println("Found: " + underline + ": " + runElement.getText(0));

                     }

                 }

-            } 

+            }

+        }

+    }

+

+

+    @Test

+    public void test56392() throws IOException, OpenXML4JException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("56392.docx");

+        assertNotNull(doc);

+    }

+

+    /**

+     * Removing a run needs to remove it from both Runs and IRuns

+     */

+    @Test

+    public void test57829() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");

+        assertNotNull(doc);

+        assertEquals(3, doc.getParagraphs().size());

+

+        for (XWPFParagraph paragraph : doc.getParagraphs()) {

+            paragraph.removeRun(0);

+            assertNotNull(paragraph.getText());

         }

     }

 }

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
index 7621404..f46fd71 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
@@ -23,7 +23,6 @@
 import java.util.List;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLProperties;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@@ -39,106 +38,105 @@
 
 public final class TestXWPFDocument extends TestCase {
 
-	public void testContainsMainContentType() throws Exception {
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
-		OPCPackage pack = doc.getPackage();
+    public void testContainsMainContentType() throws Exception {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+        OPCPackage pack = doc.getPackage();
 
-		boolean found = false;
-		for(PackagePart part : pack.getParts()) {
-			if(part.getContentType().equals(XWPFRelation.DOCUMENT.getContentType())) {
-				found = true;
-			}
-			if (false) {
-				// successful tests should be silent
-				System.out.println(part);
-			}
-		}
-		assertTrue(found);
-	}
+        boolean found = false;
+        for (PackagePart part : pack.getParts()) {
+            if (part.getContentType().equals(XWPFRelation.DOCUMENT.getContentType())) {
+                found = true;
+            }
+            if (false) {
+                // successful tests should be silent
+                System.out.println(part);
+            }
+        }
+        assertTrue(found);
+    }
 
-	public void testOpen() throws Exception {
-		XWPFDocument xml;
+    public void testOpen() throws Exception {
+        XWPFDocument xml;
 
-		// Simple file
-		xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
-		// Check it has key parts
-		assertNotNull(xml.getDocument());
-		assertNotNull(xml.getDocument().getBody());
-		assertNotNull(xml.getStyle());
+        // Simple file
+        xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
+        // Check it has key parts
+        assertNotNull(xml.getDocument());
+        assertNotNull(xml.getDocument().getBody());
+        assertNotNull(xml.getStyle());
 
-		// Complex file
-		xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
-		assertNotNull(xml.getDocument());
-		assertNotNull(xml.getDocument().getBody());
-		assertNotNull(xml.getStyle());
-	}
+        // Complex file
+        xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
+        assertNotNull(xml.getDocument());
+        assertNotNull(xml.getDocument().getBody());
+        assertNotNull(xml.getStyle());
+    }
 
-	public void testMetadataBasics() throws IOException {
-		XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
-		assertNotNull(xml.getProperties().getCoreProperties());
-		assertNotNull(xml.getProperties().getExtendedProperties());
+    public void testMetadataBasics() throws IOException {
+        XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
+        assertNotNull(xml.getProperties().getCoreProperties());
+        assertNotNull(xml.getProperties().getExtendedProperties());
 
-		assertEquals("Microsoft Office Word", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
-		assertEquals(1315, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
-		assertEquals(10, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
+        assertEquals("Microsoft Office Word", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
+        assertEquals(1315, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
+        assertEquals(10, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
 
-		assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
-		assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
-	}
+        assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
+        assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
+    }
 
-	public void testMetadataComplex() throws IOException {
-		XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
-		assertNotNull(xml.getProperties().getCoreProperties());
-		assertNotNull(xml.getProperties().getExtendedProperties());
+    public void testMetadataComplex() throws IOException {
+        XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
+        assertNotNull(xml.getProperties().getCoreProperties());
+        assertNotNull(xml.getProperties().getExtendedProperties());
 
-		assertEquals("Microsoft Office Outlook", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
-		assertEquals(5184, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
-		assertEquals(0, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
+        assertEquals("Microsoft Office Outlook", xml.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
+        assertEquals(5184, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters());
+        assertEquals(0, xml.getProperties().getExtendedProperties().getUnderlyingProperties().getLines());
 
-		assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
-		assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
-	}
+        assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
+        assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
+    }
 
-	public void testWorkbookProperties() {
-		XWPFDocument doc = new XWPFDocument();
-		POIXMLProperties props = doc.getProperties();
-		assertNotNull(props);
-		assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
-	}
-	
-	public void testAddParagraph() throws IOException{
-	   XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
-	   assertEquals(3, doc.getParagraphs().size());
+    public void testWorkbookProperties() {
+        XWPFDocument doc = new XWPFDocument();
+        POIXMLProperties props = doc.getProperties();
+        assertNotNull(props);
+        assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
+    }
 
-	   XWPFParagraph p = doc.createParagraph();
-	   assertEquals(p, doc.getParagraphs().get(3));
-	   assertEquals(4, doc.getParagraphs().size());
-	   
-	   assertEquals(3, doc.getParagraphPos(3));
-      assertEquals(3, doc.getPosOfParagraph(p));
+    public void testAddParagraph() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+        assertEquals(3, doc.getParagraphs().size());
 
-	   CTP ctp = p.getCTP();
-	   XWPFParagraph newP = doc.getParagraph(ctp);
-	   assertSame(p, newP);
-	   XmlCursor cursor = doc.getDocument().getBody().getPArray(0).newCursor();
-	   XWPFParagraph cP = doc.insertNewParagraph(cursor);
-	   assertSame(cP, doc.getParagraphs().get(0));
-	   assertEquals(5, doc.getParagraphs().size());
-	}
+        XWPFParagraph p = doc.createParagraph();
+        assertEquals(p, doc.getParagraphs().get(3));
+        assertEquals(4, doc.getParagraphs().size());
 
-    public void testAddPicture() throws IOException, InvalidFormatException
-    {
+        assertEquals(3, doc.getParagraphPos(3));
+        assertEquals(3, doc.getPosOfParagraph(p));
+
+        CTP ctp = p.getCTP();
+        XWPFParagraph newP = doc.getParagraph(ctp);
+        assertSame(p, newP);
+        XmlCursor cursor = doc.getDocument().getBody().getPArray(0).newCursor();
+        XWPFParagraph cP = doc.insertNewParagraph(cursor);
+        assertSame(cP, doc.getParagraphs().get(0));
+        assertEquals(5, doc.getParagraphs().size());
+    }
+
+    public void testAddPicture() throws IOException, InvalidFormatException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
         byte[] jpeg = XWPFTestDataSamples.getImage("nature1.jpg");
-        String relationId = doc.addPictureData(jpeg,XWPFDocument.PICTURE_TYPE_JPEG);
-        
+        String relationId = doc.addPictureData(jpeg, XWPFDocument.PICTURE_TYPE_JPEG);
+
         byte[] newJpeg = ((XWPFPictureData) doc.getRelationById(relationId)).getData();
-        assertEquals(newJpeg.length,jpeg.length);
-        for (int i = 0 ; i < jpeg.length ; i++)
-        {
-            assertEquals(newJpeg[i],jpeg[i]);
+        assertEquals(newJpeg.length, jpeg.length);
+        for (int i = 0; i < jpeg.length; i++) {
+            assertEquals(newJpeg[i], jpeg[i]);
         }
     }
+
     public void testAllPictureFormats() throws IOException, InvalidFormatException {
         XWPFDocument doc = new XWPFDocument();
 
@@ -161,184 +159,200 @@
 
     }
 
-	public void testRemoveBodyElement() throws IOException {
-	   XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
-	   assertEquals(3, doc.getParagraphs().size());
-      assertEquals(3, doc.getBodyElements().size());
-      
-      XWPFParagraph p1 = doc.getParagraphs().get(0);
-      XWPFParagraph p2 = doc.getParagraphs().get(1);
-      XWPFParagraph p3 = doc.getParagraphs().get(2);
-      
-      assertEquals(p1, doc.getBodyElements().get(0));
-      assertEquals(p1, doc.getParagraphs().get(0));
-      assertEquals(p2, doc.getBodyElements().get(1));
-      assertEquals(p2, doc.getParagraphs().get(1));
-      assertEquals(p3, doc.getBodyElements().get(2));
-      assertEquals(p3, doc.getParagraphs().get(2));
-      
-      // Add another
-      XWPFParagraph p4 = doc.createParagraph();
-      
-      assertEquals(4, doc.getParagraphs().size());
-      assertEquals(4, doc.getBodyElements().size());
-      assertEquals(p1, doc.getBodyElements().get(0));
-      assertEquals(p1, doc.getParagraphs().get(0));
-      assertEquals(p2, doc.getBodyElements().get(1));
-      assertEquals(p2, doc.getParagraphs().get(1));
-      assertEquals(p3, doc.getBodyElements().get(2));
-      assertEquals(p3, doc.getParagraphs().get(2));
-      assertEquals(p4, doc.getBodyElements().get(3));
-      assertEquals(p4, doc.getParagraphs().get(3));
-      
-      // Remove the 2nd
-      assertEquals(true, doc.removeBodyElement(1));
-      assertEquals(3, doc.getParagraphs().size());
-      assertEquals(3, doc.getBodyElements().size());
-      
-      assertEquals(p1, doc.getBodyElements().get(0));
-      assertEquals(p1, doc.getParagraphs().get(0));
-      assertEquals(p3, doc.getBodyElements().get(1));
-      assertEquals(p3, doc.getParagraphs().get(1));
-      assertEquals(p4, doc.getBodyElements().get(2));
-      assertEquals(p4, doc.getParagraphs().get(2));
-      
-      // Remove the 1st
-      assertEquals(true, doc.removeBodyElement(0));
-      assertEquals(2, doc.getParagraphs().size());
-      assertEquals(2, doc.getBodyElements().size());
-      
-      assertEquals(p3, doc.getBodyElements().get(0));
-      assertEquals(p3, doc.getParagraphs().get(0));
-      assertEquals(p4, doc.getBodyElements().get(1));
-      assertEquals(p4, doc.getParagraphs().get(1));
-      
-      // Remove the last
-      assertEquals(true, doc.removeBodyElement(1));
-      assertEquals(1, doc.getParagraphs().size());
-      assertEquals(1, doc.getBodyElements().size());
-      
-      assertEquals(p3, doc.getBodyElements().get(0));
-      assertEquals(p3, doc.getParagraphs().get(0));
-	}
-	
-	public void testRegisterPackagePictureData() throws IOException, InvalidFormatException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
-	    
-	    /* manually assemble a new image package part*/
-	    OPCPackage opcPckg = doc.getPackage();
-	    XWPFRelation jpgRelation = XWPFRelation.IMAGE_JPEG;
-	    PackagePartName partName = PackagingURIHelper.createPartName(jpgRelation.getDefaultFileName().replace('#', '2'));
+    public void testRemoveBodyElement() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+        assertEquals(3, doc.getParagraphs().size());
+        assertEquals(3, doc.getBodyElements().size());
+
+        XWPFParagraph p1 = doc.getParagraphs().get(0);
+        XWPFParagraph p2 = doc.getParagraphs().get(1);
+        XWPFParagraph p3 = doc.getParagraphs().get(2);
+
+        assertEquals(p1, doc.getBodyElements().get(0));
+        assertEquals(p1, doc.getParagraphs().get(0));
+        assertEquals(p2, doc.getBodyElements().get(1));
+        assertEquals(p2, doc.getParagraphs().get(1));
+        assertEquals(p3, doc.getBodyElements().get(2));
+        assertEquals(p3, doc.getParagraphs().get(2));
+
+        // Add another
+        XWPFParagraph p4 = doc.createParagraph();
+
+        assertEquals(4, doc.getParagraphs().size());
+        assertEquals(4, doc.getBodyElements().size());
+        assertEquals(p1, doc.getBodyElements().get(0));
+        assertEquals(p1, doc.getParagraphs().get(0));
+        assertEquals(p2, doc.getBodyElements().get(1));
+        assertEquals(p2, doc.getParagraphs().get(1));
+        assertEquals(p3, doc.getBodyElements().get(2));
+        assertEquals(p3, doc.getParagraphs().get(2));
+        assertEquals(p4, doc.getBodyElements().get(3));
+        assertEquals(p4, doc.getParagraphs().get(3));
+
+        // Remove the 2nd
+        assertEquals(true, doc.removeBodyElement(1));
+        assertEquals(3, doc.getParagraphs().size());
+        assertEquals(3, doc.getBodyElements().size());
+
+        assertEquals(p1, doc.getBodyElements().get(0));
+        assertEquals(p1, doc.getParagraphs().get(0));
+        assertEquals(p3, doc.getBodyElements().get(1));
+        assertEquals(p3, doc.getParagraphs().get(1));
+        assertEquals(p4, doc.getBodyElements().get(2));
+        assertEquals(p4, doc.getParagraphs().get(2));
+
+        // Remove the 1st
+        assertEquals(true, doc.removeBodyElement(0));
+        assertEquals(2, doc.getParagraphs().size());
+        assertEquals(2, doc.getBodyElements().size());
+
+        assertEquals(p3, doc.getBodyElements().get(0));
+        assertEquals(p3, doc.getParagraphs().get(0));
+        assertEquals(p4, doc.getBodyElements().get(1));
+        assertEquals(p4, doc.getParagraphs().get(1));
+
+        // Remove the last
+        assertEquals(true, doc.removeBodyElement(1));
+        assertEquals(1, doc.getParagraphs().size());
+        assertEquals(1, doc.getBodyElements().size());
+
+        assertEquals(p3, doc.getBodyElements().get(0));
+        assertEquals(p3, doc.getParagraphs().get(0));
+    }
+
+    public void testRegisterPackagePictureData() throws IOException, InvalidFormatException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
+
+        /* manually assemble a new image package part*/
+        OPCPackage opcPckg = doc.getPackage();
+        XWPFRelation jpgRelation = XWPFRelation.IMAGE_JPEG;
+        PackagePartName partName = PackagingURIHelper.createPartName(jpgRelation.getDefaultFileName().replace('#', '2'));
         PackagePart newImagePart = opcPckg.createPart(partName, jpgRelation.getContentType());
         byte[] nature1 = XWPFTestDataSamples.getImage("abstract4.jpg");
         OutputStream os = newImagePart.getOutputStream();
         os.write(nature1);
-	    os.close();
-	    XWPFHeader xwpfHeader = doc.getHeaderArray(0);
-	    PackageRelationship relationship = xwpfHeader.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, jpgRelation.getRelation());
-	    XWPFPictureData newPicData = new XWPFPictureData(newImagePart,relationship);
-	    /* new part is now ready to rumble */
-	    
-	    assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
-	    assertFalse(doc.getAllPictures().contains(newPicData));
-	    assertFalse(doc.getAllPackagePictures().contains(newPicData));
+        os.close();
+        XWPFHeader xwpfHeader = doc.getHeaderArray(0);
+        PackageRelationship relationship = xwpfHeader.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, jpgRelation.getRelation());
+        XWPFPictureData newPicData = new XWPFPictureData(newImagePart, relationship);
+        /* new part is now ready to rumble */
 
-	    doc.registerPackagePictureData(newPicData);
-	    
-	    assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
-	    assertFalse(doc.getAllPictures().contains(newPicData));
-	    assertTrue(doc.getAllPackagePictures().contains(newPicData));
-	    
-	    doc.getPackage().revert();
-	}
+        assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
+        assertFalse(doc.getAllPictures().contains(newPicData));
+        assertFalse(doc.getAllPackagePictures().contains(newPicData));
 
-	public void testFindPackagePictureData() throws IOException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
-	    byte[] nature1 = XWPFTestDataSamples.getImage("nature1.gif");
-	    XWPFPictureData part = doc.findPackagePictureData(nature1, Document.PICTURE_TYPE_GIF);
-	    assertNotNull(part);
-	    assertTrue(doc.getAllPictures().contains(part));
-	    assertTrue(doc.getAllPackagePictures().contains(part));
-	    doc.getPackage().revert();
-	}
-	
-	public void testGetAllPictures() throws IOException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
-	    List<XWPFPictureData> allPictures = doc.getAllPictures();
-	    List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
-	    
-	    assertNotNull(allPictures);
-	    assertEquals(3,allPictures.size());
-	    for (XWPFPictureData xwpfPictureData : allPictures) {
-	        assertTrue(allPackagePictures.contains(xwpfPictureData));
+        doc.registerPackagePictureData(newPicData);
+
+        assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
+        assertFalse(doc.getAllPictures().contains(newPicData));
+        assertTrue(doc.getAllPackagePictures().contains(newPicData));
+
+        doc.getPackage().revert();
+    }
+
+    public void testFindPackagePictureData() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
+        byte[] nature1 = XWPFTestDataSamples.getImage("nature1.gif");
+        XWPFPictureData part = doc.findPackagePictureData(nature1, Document.PICTURE_TYPE_GIF);
+        assertNotNull(part);
+        assertTrue(doc.getAllPictures().contains(part));
+        assertTrue(doc.getAllPackagePictures().contains(part));
+        doc.getPackage().revert();
+    }
+
+    public void testGetAllPictures() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
+        List<XWPFPictureData> allPictures = doc.getAllPictures();
+        List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
+
+        assertNotNull(allPictures);
+        assertEquals(3, allPictures.size());
+        for (XWPFPictureData xwpfPictureData : allPictures) {
+            assertTrue(allPackagePictures.contains(xwpfPictureData));
         }
 
-	    try {
+        try {
             allPictures.add(allPictures.get(0));
             fail("This list must be unmodifiable!");
         } catch (UnsupportedOperationException e) {
             // all ok
         }
-	    
-	    doc.getPackage().revert();
-	}
 
-	public void testGetAllPackagePictures() throws IOException {
-	       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
-	        List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
-	        
-	        assertNotNull(allPackagePictures);
-	        assertEquals(5,allPackagePictures.size());
+        doc.getPackage().revert();
+    }
 
-	        try {
-	            allPackagePictures.add(allPackagePictures.get(0));
-	            fail("This list must be unmodifiable!");
-	        } catch (UnsupportedOperationException e) {
-	            // all ok
-	        }
-	        
-	        doc.getPackage().revert();
-	}
-	
-	public void testPictureHandlingSimpleFile() throws IOException, InvalidFormatException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
-	    assertEquals(1,doc.getAllPackagePictures().size());
-	    byte[] newPic = XWPFTestDataSamples.getImage("abstract4.jpg");
-	    String id1 = doc.addPictureData(newPic, Document.PICTURE_TYPE_JPEG);
-	    assertEquals(2,doc.getAllPackagePictures().size());
-	    /* copy data, to avoid instance-equality */
-	    byte[] newPicCopy = Arrays.copyOf(newPic, newPic.length);
-	    String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG);
-	    assertEquals(id1,id2);
-	    doc.getPackage().revert();
-	}
-	
-	public void testPictureHandlingHeaderDocumentImages() throws IOException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx");
-	    assertEquals(1,doc.getAllPictures().size());
-	    assertEquals(1,doc.getAllPackagePictures().size());
-	    assertEquals(1,doc.getHeaderArray(0).getAllPictures().size());
-	    doc.getPackage().revert();
-	}
-	
-	public void testPictureHandlingComplex() throws IOException, InvalidFormatException {
-	    XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
-	    XWPFHeader xwpfHeader = doc.getHeaderArray(0);
+    public void testGetAllPackagePictures() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
+        List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
 
-	    assertEquals(3,doc.getAllPictures().size());
-        assertEquals(3,xwpfHeader.getAllPictures().size());
-	    assertEquals(5,doc.getAllPackagePictures().size());
-	    
-	    byte[] nature1 = XWPFTestDataSamples.getImage("nature1.jpg");
-	    String id = doc.addPictureData(nature1, Document.PICTURE_TYPE_JPEG);
-	    POIXMLDocumentPart part1 = xwpfHeader.getRelationById("rId1");
-	    XWPFPictureData part2 = (XWPFPictureData) doc.getRelationById(id);
-	    assertSame(part1,part2);
-	    
-	    doc.getPackage().revert();
-	}
+        assertNotNull(allPackagePictures);
+        assertEquals(5, allPackagePictures.size());
 
-    public void testSettings(){
+        try {
+            allPackagePictures.add(allPackagePictures.get(0));
+            fail("This list must be unmodifiable!");
+        } catch (UnsupportedOperationException e) {
+            // all ok
+        }
+
+        doc.getPackage().revert();
+    }
+
+    public void testPictureHandlingSimpleFile() throws IOException, InvalidFormatException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
+        assertEquals(1, doc.getAllPackagePictures().size());
+        byte[] newPic = XWPFTestDataSamples.getImage("abstract4.jpg");
+        String id1 = doc.addPictureData(newPic, Document.PICTURE_TYPE_JPEG);
+        assertEquals(2, doc.getAllPackagePictures().size());
+        /* copy data, to avoid instance-equality */
+        byte[] newPicCopy = Arrays.copyOf(newPic, newPic.length);
+        String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG);
+        assertEquals(id1, id2);
+        doc.getPackage().revert();
+    }
+
+    public void testPictureHandlingHeaderDocumentImages() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx");
+        assertEquals(1, doc.getAllPictures().size());
+        assertEquals(1, doc.getAllPackagePictures().size());
+        assertEquals(1, doc.getHeaderArray(0).getAllPictures().size());
+        doc.getPackage().revert();
+    }
+
+    public void testPictureHandlingComplex() throws IOException, InvalidFormatException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
+        XWPFHeader xwpfHeader = doc.getHeaderArray(0);
+
+        assertEquals(3, doc.getAllPictures().size());
+        assertEquals(3, xwpfHeader.getAllPictures().size());
+        assertEquals(5, doc.getAllPackagePictures().size());
+
+        byte[] nature1 = XWPFTestDataSamples.getImage("nature1.jpg");
+        String id = doc.addPictureData(nature1, Document.PICTURE_TYPE_JPEG);
+        POIXMLDocumentPart part1 = xwpfHeader.getRelationById("rId1");
+        XWPFPictureData part2 = (XWPFPictureData) doc.getRelationById(id);
+        assertSame(part1, part2);
+
+        doc.getPackage().revert();
+    }
+
+    public void testZeroLengthLibreOfficeDocumentWithWaterMarkHeader() throws IOException {
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("zero-length.docx");
+        POIXMLProperties properties = doc.getProperties();
+
+        assertNotNull(properties.getCoreProperties());
+
+        XWPFHeader headerArray = doc.getHeaderArray(0);
+        assertEquals(1, headerArray.getAllPictures().size());
+        assertEquals("image1.png", headerArray.pictures.get(0).getFileName());
+        assertEquals("", headerArray.getText());
+
+        POIXMLProperties.ExtendedProperties extendedProperties = properties.getExtendedProperties();
+        assertNotNull(extendedProperties);
+        assertEquals(0, extendedProperties.getUnderlyingProperties().getCharacters());
+    }
+
+    public void testSettings() {
         XWPFSettings settings = new XWPFSettings();
         settings.setZoomPercent(50);
         assertEquals(50, settings.getZoomPercent());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java
index fb97bf5..0915de0 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java
@@ -19,52 +19,50 @@
 
 import java.io.IOException;
 import java.math.BigInteger;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFtnEdn;
-
-public class TestXWPFFootnotes extends TestCase {
-
-	public void testAddFootnotesToDocument() throws IOException{
-		XWPFDocument docOut = new XWPFDocument();
-
-		BigInteger noteId = BigInteger.valueOf(1);
-
-		XWPFFootnotes footnotes = docOut.createFootnotes();
-		CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance();
-		ctNote.setId(noteId);
-		ctNote.setType(STFtnEdn.NORMAL);
-		footnotes.addFootnote(ctNote);
-
-		XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);
-
-		XWPFFootnote note = docIn.getFootnoteByID(noteId.intValue());
-		assertEquals(note.getCTFtnEdn().getType(), STFtnEdn.NORMAL);
-	}
-
-   /**
-    * Bug 55066 - avoid double loading the footnotes
-    */
-	public void testLoadFootnotesOnce() throws IOException{
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
-		List<XWPFFootnote> footnotes = doc.getFootnotes();
-		int hits = 0;
-		for (XWPFFootnote fn : footnotes){
-			for (IBodyElement e : fn.getBodyElements()){
-				if (e instanceof XWPFParagraph){
-					String txt = ((XWPFParagraph)e).getText();
-					if (txt.indexOf("Footnote_sdt") > -1){
-						hits++;
-					}
-				}
-			}
-		}
-		assertEquals("Load footnotes once", 1, hits);
-	}
-}
-
+import java.util.List;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFtnEdn;

+

+public class TestXWPFFootnotes extends TestCase {

+

+    public void testAddFootnotesToDocument() throws IOException {

+        XWPFDocument docOut = new XWPFDocument();

+

+        BigInteger noteId = BigInteger.valueOf(1);

+

+        XWPFFootnotes footnotes = docOut.createFootnotes();

+        CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance();

+        ctNote.setId(noteId);

+        ctNote.setType(STFtnEdn.NORMAL);

+        footnotes.addFootnote(ctNote);

+

+        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);

+

+        XWPFFootnote note = docIn.getFootnoteByID(noteId.intValue());

+        assertEquals(note.getCTFtnEdn().getType(), STFtnEdn.NORMAL);

+    }

+

+    /**

+     * Bug 55066 - avoid double loading the footnotes

+     */

+    public void testLoadFootnotesOnce() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");

+        List<XWPFFootnote> footnotes = doc.getFootnotes();

+        int hits = 0;

+        for (XWPFFootnote fn : footnotes) {

+            for (IBodyElement e : fn.getBodyElements()) {

+                if (e instanceof XWPFParagraph) {

+                    String txt = ((XWPFParagraph) e).getText();

+                    if (txt.indexOf("Footnote_sdt") > -1) {

+                        hits++;

+                    }

+                }

+            }

+        }

+        assertEquals("Load footnotes once", 1, hits);

+    }

+}

+

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
index a607d0e..172c0eb 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
@@ -17,13 +17,12 @@
 
 package org.apache.poi.xwpf.usermodel;
 
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;

 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
 
@@ -159,25 +158,25 @@
         assertEquals("First paragraph for the footer", paras[0].getText());
         assertEquals("Second paragraph for the footer", paras[1].getText());
     }
-
-    public void testSetWatermark() throws IOException {
-        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
-        
-        // No header is set (yet)
-        XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
-        assertNull(policy.getDefaultHeader());
+

+    public void testSetWatermark() throws IOException {

+        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");

+

+        // No header is set (yet)

+        XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();

+        assertNull(policy.getDefaultHeader());

         assertNull(policy.getFirstPageHeader());
         assertNull(policy.getDefaultFooter());
 
         policy.createWatermark("DRAFT");
 
-        assertNotNull(policy.getDefaultHeader());
-        assertNotNull(policy.getFirstPageHeader());
-        assertNotNull(policy.getEvenPageHeader());
-        
-        // Re-open, and check
-        XWPFDocument reopened = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc);
-        policy = reopened.getHeaderFooterPolicy();
+        assertNotNull(policy.getDefaultHeader());

+        assertNotNull(policy.getFirstPageHeader());

+        assertNotNull(policy.getEvenPageHeader());

+

+        // Re-open, and check

+        XWPFDocument reopened = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc);

+        policy = reopened.getHeaderFooterPolicy();

 
         assertNotNull(policy.getDefaultHeader());
         assertNotNull(policy.getFirstPageHeader());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java
index ca74d81..b084634 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeadings.java
@@ -16,39 +16,38 @@
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
-import java.io.IOException;
+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.apache.xmlbeans.XmlException;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;

 
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
-
-/**
- * @author Paolo Mottadelli
- */
-public final class TestXWPFHeadings extends TestCase{
-	private static final String HEADING1 = "Heading1";
-
-	public void testSetParagraphStyle() throws IOException, XmlException {
-		//new clean instance of paragraph
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("heading123.docx");
-		XWPFParagraph p = doc.createParagraph();
-		XWPFRun run = p.createRun();
-		run.setText("Heading 1");
-
-		CTSdtBlock block = doc.getDocument().getBody().addNewSdt();
-
-		assertNull(p.getStyle());
-		p.setStyle(HEADING1);
-		assertEquals(HEADING1, p.getCTP().getPPr().getPStyle().getVal());
-
-		doc.createTOC();
-        /*
-		// TODO - finish this test
-		if (false) {
-			CTStyles styles = doc.getStyle();
-			CTStyle style = styles.addNewStyle();
+/**

+ * @author Paolo Mottadelli

+ */

+public final class TestXWPFHeadings extends TestCase {

+    private static final String HEADING1 = "Heading1";

+

+    public void testSetParagraphStyle() throws IOException, XmlException {

+        //new clean instance of paragraph

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("heading123.docx");

+        XWPFParagraph p = doc.createParagraph();

+        XWPFRun run = p.createRun();

+        run.setText("Heading 1");

+

+        CTSdtBlock block = doc.getDocument().getBody().addNewSdt();

+

+        assertNull(p.getStyle());

+        p.setStyle(HEADING1);

+        assertEquals(HEADING1, p.getCTP().getPPr().getPStyle().getVal());

+

+        doc.createTOC();

+        /*

+        // TODO - finish this test

+		if (false) {

+			CTStyles styles = doc.getStyle();

+			CTStyle style = styles.addNewStyle();

 			style.setType(STStyleType.PARAGRAPH);
 			style.setStyleId("Heading1");
 		}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
index fce9d18..dfdecc9 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
@@ -18,60 +18,85 @@
 package org.apache.poi.xwpf.usermodel;
 
 import java.io.IOException;
-import java.math.BigInteger;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-
-public class TestXWPFNumbering extends TestCase {
-	
-	public void testCompareAbstractNum() throws IOException{
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
-		XWPFNumbering numbering = doc.getNumbering();
-		BigInteger numId = BigInteger.valueOf(1);
-		assertTrue(numbering.numExist(numId));
-		XWPFNum num = numbering.getNum(numId);
-		BigInteger abstrNumId = num.getCTNum().getAbstractNumId().getVal();
-		XWPFAbstractNum abstractNum = numbering.getAbstractNum(abstrNumId);
-		BigInteger compareAbstractNum = numbering.getIdOfAbstractNum(abstractNum);
-		assertEquals(abstrNumId, compareAbstractNum);
-	}
-
-	public void testAddNumberingToDoc() throws IOException{
-		BigInteger abstractNumId = BigInteger.valueOf(1);
-		BigInteger numId = BigInteger.valueOf(1);
-
-		XWPFDocument docOut = new XWPFDocument();
-		XWPFNumbering numbering = docOut.createNumbering();
-		numId = numbering.addNum(abstractNumId);
-		
-		XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);
-
-		numbering = docIn.getNumbering();
-		assertTrue(numbering.numExist(numId));
-		XWPFNum num = numbering.getNum(numId);
-
-		BigInteger compareAbstractNum = num.getCTNum().getAbstractNumId().getVal();
-		assertEquals(abstractNumId, compareAbstractNum);
-	}
-
-	public void testGetNumIlvl() throws IOException{
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
-		BigInteger numIlvl = BigInteger.valueOf(0);
-		assertEquals(numIlvl, doc.getParagraphs().get(0).getNumIlvl());
-		numIlvl = BigInteger.valueOf(1);
-      assertEquals(numIlvl, doc.getParagraphs().get(5).getNumIlvl());
-	}
-
-	public void testGetNumFmt() throws IOException{
-		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
-		assertEquals("bullet", doc.getParagraphs().get(0).getNumFmt());
-		assertEquals("bullet", doc.getParagraphs().get(1).getNumFmt());
-		assertEquals("bullet", doc.getParagraphs().get(2).getNumFmt());
-		assertEquals("bullet", doc.getParagraphs().get(3).getNumFmt());
-		assertEquals("decimal", doc.getParagraphs().get(4).getNumFmt());
-		assertEquals("lowerLetter", doc.getParagraphs().get(5).getNumFmt());
-		assertEquals("lowerRoman", doc.getParagraphs().get(6).getNumFmt());
-  }
-}
+import java.math.BigInteger;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumLvl;

+

+public class TestXWPFNumbering extends TestCase {

+

+    public void testCompareAbstractNum() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");

+        XWPFNumbering numbering = doc.getNumbering();

+        BigInteger numId = BigInteger.valueOf(1);

+        assertTrue(numbering.numExist(numId));

+        XWPFNum num = numbering.getNum(numId);

+        BigInteger abstrNumId = num.getCTNum().getAbstractNumId().getVal();

+        XWPFAbstractNum abstractNum = numbering.getAbstractNum(abstrNumId);

+        BigInteger compareAbstractNum = numbering.getIdOfAbstractNum(abstractNum);

+        assertEquals(abstrNumId, compareAbstractNum);

+    }

+

+    public void testAddNumberingToDoc() throws IOException {

+        BigInteger abstractNumId = BigInteger.valueOf(1);

+        BigInteger numId = BigInteger.valueOf(1);

+

+        XWPFDocument docOut = new XWPFDocument();

+        XWPFNumbering numbering = docOut.createNumbering();

+        numId = numbering.addNum(abstractNumId);

+

+        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);

+

+        numbering = docIn.getNumbering();

+        assertTrue(numbering.numExist(numId));

+        XWPFNum num = numbering.getNum(numId);

+

+        BigInteger compareAbstractNum = num.getCTNum().getAbstractNumId().getVal();

+        assertEquals(abstractNumId, compareAbstractNum);

+    }

+

+    public void testGetNumIlvl() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");

+        BigInteger numIlvl = BigInteger.valueOf(0);

+        assertEquals(numIlvl, doc.getParagraphs().get(0).getNumIlvl());

+        numIlvl = BigInteger.valueOf(1);

+        assertEquals(numIlvl, doc.getParagraphs().get(5).getNumIlvl());

+    }

+

+    public void testGetNumFmt() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");

+        assertEquals("bullet", doc.getParagraphs().get(0).getNumFmt());

+        assertEquals("bullet", doc.getParagraphs().get(1).getNumFmt());

+        assertEquals("bullet", doc.getParagraphs().get(2).getNumFmt());

+        assertEquals("bullet", doc.getParagraphs().get(3).getNumFmt());

+        assertEquals("decimal", doc.getParagraphs().get(4).getNumFmt());

+        assertEquals("lowerLetter", doc.getParagraphs().get(5).getNumFmt());

+        assertEquals("lowerRoman", doc.getParagraphs().get(6).getNumFmt());

+    }

+

+    public void testLvlText() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");

+

+        assertEquals("%1.%2.%3.", doc.getParagraphs().get(12).getNumLevelText());

+

+        assertEquals("NEW-%1-FORMAT", doc.getParagraphs().get(14).getNumLevelText());

+

+        XWPFParagraph p = doc.getParagraphs().get(18);

+        assertEquals("%1.", p.getNumLevelText());

+        //test that null doesn't throw NPE

+        assertNull(p.getNumFmt());

+    }

+

+    public void testOverrideList() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("NumberingWOverrides.docx");

+        XWPFParagraph p = doc.getParagraphs().get(4);

+        XWPFNumbering numbering = doc.getNumbering();

+        CTNum ctNum = numbering.getNum(p.getNumID()).getCTNum();

+        assertEquals(9, ctNum.sizeOfLvlOverrideArray());

+        CTNumLvl ctNumLvl = ctNum.getLvlOverrideArray(0);

+        assertEquals("upperLetter", ctNumLvl.getLvl().getNumFmt().getVal().toString());

+    }

+

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
index ec17da4..31be821 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
@@ -22,12 +22,26 @@
 import java.util.List;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
 import org.openxmlformats.schemas.drawingml.x2006.picture.PicDocument;
 import org.openxmlformats.schemas.drawingml.x2006.picture.impl.PicDocumentImpl;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
 
 /**
  * Tests for XWPF Paragraphs
@@ -36,7 +50,8 @@
 
     /**
      * Check that we get the right paragraph from the header
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void disabled_testHeaderParagraph() throws IOException {
         XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
@@ -44,7 +59,7 @@
         XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader();
         assertNotNull(hdr);
 
-       List<XWPFParagraph> ps =  hdr.getParagraphs();
+        List<XWPFParagraph> ps = hdr.getParagraphs();
         assertEquals(1, ps.size());
         XWPFParagraph p = ps.get(0);
 
@@ -55,7 +70,8 @@
 
     /**
      * Check that we get the right paragraphs from the document
-     * @throws IOException 
+     *
+     * @throws IOException
      */
     public void disabled_testDocumentParagraph() throws IOException {
         XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
@@ -88,7 +104,7 @@
         assertEquals(STBorder.NONE.intValue(), p.getBorderTop().getValue());
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         //bordi
         CTPBdr bdr = ppr.addNewPBdr();
@@ -109,7 +125,7 @@
         assertEquals(STJc.LEFT.intValue(), p.getAlignment().getValue());
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         CTJc align = ppr.addNewJc();
         align.setVal(STJc.CENTER);
@@ -125,7 +141,7 @@
         XWPFParagraph p = doc.createParagraph();
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         assertEquals(-1, p.getSpacingAfter());
 
@@ -142,7 +158,7 @@
         XWPFParagraph p = doc.createParagraph();
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         assertEquals(STLineSpacingRule.INT_AUTO, p.getSpacingLineRule().getValue());
 
@@ -161,7 +177,7 @@
         assertEquals(-1, p.getIndentationLeft());
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         assertEquals(-1, p.getIndentationLeft());
 
@@ -179,7 +195,7 @@
         XWPFParagraph p = doc.createParagraph();
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         CTTextAlignment txtAlign = ppr.addNewTextAlignment();
         txtAlign.setVal(STTextAlignment.CENTER);
@@ -194,7 +210,7 @@
         XWPFParagraph p = doc.createParagraph();
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         CTOnOff wordWrap = ppr.addNewWordWrap();
         wordWrap.setVal(STOnOff.FALSE);
@@ -210,7 +226,7 @@
         XWPFParagraph p = doc.createParagraph();
 
         CTP ctp = p.getCTP();
-        CTPPr ppr = ctp.getPPr()== null? ctp.addNewPPr() : ctp.getPPr();
+        CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
         CTOnOff pageBreak = ppr.addNewPageBreakBefore();
         pageBreak.setVal(STOnOff.FALSE);
@@ -229,8 +245,8 @@
         assertEquals(0, paragraph.getCTP().sizeOfBookmarkEndArray());
         CTBookmark ctBookmark = paragraph.getCTP().getBookmarkStartArray(0);
         assertEquals("poi", ctBookmark.getName());
-        for(CTBookmark bookmark : paragraph.getCTP().getBookmarkStartArray()) {
-           assertEquals("poi", bookmark.getName());
+        for (CTBookmark bookmark : paragraph.getCTP().getBookmarkStartArray()) {
+            assertEquals("poi", bookmark.getName());
         }
     }
 
@@ -241,108 +257,108 @@
         p.setNumID(new BigInteger("10"));
         assertEquals("10", p.getNumID().toString());
     }
-    
+
     public void testAddingRuns() throws Exception {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
-     
-       XWPFParagraph p = doc.getParagraphs().get(0);
-       assertEquals(2, p.getRuns().size());
-       
-       XWPFRun r = p.createRun();
-       assertEquals(3, p.getRuns().size());
-       assertEquals(2, p.getRuns().indexOf(r));
-       
-       XWPFRun r2 = p.insertNewRun(1);
-       assertEquals(4, p.getRuns().size());
-       assertEquals(1, p.getRuns().indexOf(r2));
-       assertEquals(3, p.getRuns().indexOf(r));
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+
+        XWPFParagraph p = doc.getParagraphs().get(0);
+        assertEquals(2, p.getRuns().size());
+
+        XWPFRun r = p.createRun();
+        assertEquals(3, p.getRuns().size());
+        assertEquals(2, p.getRuns().indexOf(r));
+
+        XWPFRun r2 = p.insertNewRun(1);
+        assertEquals(4, p.getRuns().size());
+        assertEquals(1, p.getRuns().indexOf(r2));
+        assertEquals(3, p.getRuns().indexOf(r));
     }
-    
+
     public void testPictures() throws Exception {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
-       assertEquals(7, doc.getParagraphs().size());
-       
-       XWPFParagraph p;
-       XWPFRun r;
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
+        assertEquals(7, doc.getParagraphs().size());
 
-       // Text paragraphs
-       assertEquals("Sheet with various pictures", doc.getParagraphs().get(0).getText());
-       assertEquals("(jpeg, png, wmf, emf and pict) ", doc.getParagraphs().get(1).getText());
-       
-       // Spacer ones
-       assertEquals("", doc.getParagraphs().get(2).getText());
-       assertEquals("", doc.getParagraphs().get(3).getText());
-       assertEquals("", doc.getParagraphs().get(4).getText());
-       
-       // Image one
-       p = doc.getParagraphs().get(5);
-       assertEquals(6, p.getRuns().size());
+        XWPFParagraph p;
+        XWPFRun r;
 
-       r = p.getRuns().get(0);
-       assertEquals("", r.toString());
-       assertEquals(1, r.getEmbeddedPictures().size());
-       assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
-       assertEquals("image1.wmf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+        // Text paragraphs
+        assertEquals("Sheet with various pictures", doc.getParagraphs().get(0).getText());
+        assertEquals("(jpeg, png, wmf, emf and pict) ", doc.getParagraphs().get(1).getText());
 
-       r = p.getRuns().get(1);
-       assertEquals("", r.toString());
-       assertEquals(1, r.getEmbeddedPictures().size());
-       assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
-       assertEquals("image2.png", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+        // Spacer ones
+        assertEquals("", doc.getParagraphs().get(2).getText());
+        assertEquals("", doc.getParagraphs().get(3).getText());
+        assertEquals("", doc.getParagraphs().get(4).getText());
 
-       r = p.getRuns().get(2);
-       assertEquals("", r.toString());
-       assertEquals(1, r.getEmbeddedPictures().size());
-       assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
-       assertEquals("image3.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+        // Image one
+        p = doc.getParagraphs().get(5);
+        assertEquals(6, p.getRuns().size());
 
-       r = p.getRuns().get(3);
-       assertEquals("", r.toString());
-       assertEquals(1, r.getEmbeddedPictures().size());
-       assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
-       assertEquals("image4.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+        r = p.getRuns().get(0);
+        assertEquals("", r.toString());
+        assertEquals(1, r.getEmbeddedPictures().size());
+        assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
+        assertEquals("image1.wmf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
 
-       r = p.getRuns().get(4);
-       assertEquals("", r.toString());
-       assertEquals(1, r.getEmbeddedPictures().size());
-       assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
-       assertEquals("image5.jpeg", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
-       
-       r = p.getRuns().get(5);
-       assertEquals(" ", r.toString());
-       assertEquals(0, r.getEmbeddedPictures().size());
-       
-       // Final spacer
-       assertEquals("", doc.getParagraphs().get(6).getText());
-       
-       
-       // Look in detail at one
-       r = p.getRuns().get(4);
-       XWPFPicture pict = r.getEmbeddedPictures().get(0);
-       CTPicture picture = pict.getCTPicture();
-       assertEquals("rId8", picture.getBlipFill().getBlip().getEmbed());
-       
-       // Ensure that the ooxml compiler finds everything we need
-       r.getCTR().getDrawingArray(0);
-       r.getCTR().getDrawingArray(0).getInlineArray(0);
-       r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic();
-       r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic().getGraphicData();
-       PicDocument pd = new PicDocumentImpl(null);
-       assertTrue(pd.isNil());
+        r = p.getRuns().get(1);
+        assertEquals("", r.toString());
+        assertEquals(1, r.getEmbeddedPictures().size());
+        assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
+        assertEquals("image2.png", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+
+        r = p.getRuns().get(2);
+        assertEquals("", r.toString());
+        assertEquals(1, r.getEmbeddedPictures().size());
+        assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
+        assertEquals("image3.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+
+        r = p.getRuns().get(3);
+        assertEquals("", r.toString());
+        assertEquals(1, r.getEmbeddedPictures().size());
+        assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
+        assertEquals("image4.emf", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+
+        r = p.getRuns().get(4);
+        assertEquals("", r.toString());
+        assertEquals(1, r.getEmbeddedPictures().size());
+        assertNotNull(r.getEmbeddedPictures().get(0).getPictureData());
+        assertEquals("image5.jpeg", r.getEmbeddedPictures().get(0).getPictureData().getFileName());
+
+        r = p.getRuns().get(5);
+        assertEquals(" ", r.toString());
+        assertEquals(0, r.getEmbeddedPictures().size());
+
+        // Final spacer
+        assertEquals("", doc.getParagraphs().get(6).getText());
+
+
+        // Look in detail at one
+        r = p.getRuns().get(4);
+        XWPFPicture pict = r.getEmbeddedPictures().get(0);
+        CTPicture picture = pict.getCTPicture();
+        assertEquals("rId8", picture.getBlipFill().getBlip().getEmbed());
+
+        // Ensure that the ooxml compiler finds everything we need
+        r.getCTR().getDrawingArray(0);
+        r.getCTR().getDrawingArray(0).getInlineArray(0);
+        r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic();
+        r.getCTR().getDrawingArray(0).getInlineArray(0).getGraphic().getGraphicData();
+        PicDocument pd = new PicDocumentImpl(null);
+        assertTrue(pd.isNil());
     }
-    
-    public void testTika792() throws Exception{
-       //This test forces the loading of CTMoveBookmark and
-       //CTMoveBookmarkImpl into ooxml-lite.
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Tika-792.docx");
-       XWPFParagraph paragraph = doc.getParagraphs().get(0);
-       assertEquals("s", paragraph.getText());
+
+    public void testTika792() throws Exception {
+        //This test forces the loading of CTMoveBookmark and
+        //CTMoveBookmarkImpl into ooxml-lite.
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Tika-792.docx");
+        XWPFParagraph paragraph = doc.getParagraphs().get(0);
+        assertEquals("s", paragraph.getText());
     }
 
     public void testSettersGetters() {
         XWPFDocument doc = new XWPFDocument();
         XWPFParagraph p = doc.createParagraph();
-        
+
         assertTrue(p.isEmpty());
         assertFalse(p.removeRun(0));
 
@@ -355,7 +371,7 @@
         assertFalse(p.isEmpty());
         assertNull(p.getStyleID());
         assertNull(p.getStyle());
-        
+
         assertNull(p.getNumID());
         p.setNumID(BigInteger.valueOf(12));
         assertEquals(BigInteger.valueOf(12), p.getNumID());
@@ -363,18 +379,18 @@
         assertEquals(BigInteger.valueOf(13), p.getNumID());
 
         assertNull(p.getNumFmt());
-        
+
         assertNull(p.getNumIlvl());
-        
+
         assertEquals("", p.getParagraphText());
         assertEquals("", p.getPictureText());
         assertEquals("", p.getFootnoteText());
-        
+
         p.setBorderBetween(Borders.NONE);
         assertEquals(Borders.NONE, p.getBorderBetween());
         p.setBorderBetween(Borders.BASIC_BLACK_DASHES);
         assertEquals(Borders.BASIC_BLACK_DASHES, p.getBorderBetween());
-        
+
         p.setBorderBottom(Borders.NONE);
         assertEquals(Borders.NONE, p.getBorderBottom());
         p.setBorderBottom(Borders.BABY_RATTLE);
@@ -394,37 +410,37 @@
         assertEquals(Borders.NONE, p.getBorderBottom());
         p.setBorderBottom(Borders.BASIC_WHITE_DOTS);
         assertEquals(Borders.BASIC_WHITE_DOTS, p.getBorderBottom());
-        
+
         assertFalse(p.isPageBreak());
         p.setPageBreak(true);
         assertTrue(p.isPageBreak());
         p.setPageBreak(false);
         assertFalse(p.isPageBreak());
-        
+
         assertEquals(-1, p.getSpacingAfter());
         p.setSpacingAfter(12);
         assertEquals(12, p.getSpacingAfter());
-        
+
         assertEquals(-1, p.getSpacingAfterLines());
         p.setSpacingAfterLines(14);
         assertEquals(14, p.getSpacingAfterLines());
-        
+
         assertEquals(-1, p.getSpacingBefore());
         p.setSpacingBefore(16);
         assertEquals(16, p.getSpacingBefore());
-        
+
         assertEquals(-1, p.getSpacingBeforeLines());
         p.setSpacingBeforeLines(18);
         assertEquals(18, p.getSpacingBeforeLines());
-        
+
         assertEquals(LineSpacingRule.AUTO, p.getSpacingLineRule());
         p.setSpacingLineRule(LineSpacingRule.EXACT);
         assertEquals(LineSpacingRule.EXACT, p.getSpacingLineRule());
-        
+
         assertEquals(-1, p.getIndentationLeft());
         p.setIndentationLeft(21);
         assertEquals(21, p.getIndentationLeft());
-        
+
         assertEquals(-1, p.getIndentationRight());
         p.setIndentationRight(25);
         assertEquals(25, p.getIndentationRight());
@@ -442,20 +458,20 @@
         assertTrue(p.isWordWrap());
         p.setWordWrap(false);
         assertFalse(p.isWordWrap());
-        
+
         assertNull(p.getStyle());
         p.setStyle("teststyle");
         assertEquals("teststyle", p.getStyle());
-        
+
         p.addRun(CTR.Factory.newInstance());
-        
+
         //assertTrue(p.removeRun(0));
-        
+
         assertNotNull(p.getBody());
         assertEquals(BodyElementType.PARAGRAPH, p.getElementType());
         assertEquals(BodyType.DOCUMENT, p.getPartType());
     }
-    
+
     public void testSearchTextNotFound() {
         XWPFDocument doc = new XWPFDocument();
         XWPFParagraph p = doc.createParagraph();
@@ -469,17 +485,17 @@
 
         List<XWPFParagraph> ps = xml.getParagraphs();
         assertEquals(10, ps.size());
-        
+
         XWPFParagraph p = ps.get(0);
 
         TextSegement segment = p.searchText("sample word document", new PositionInParagraph());
         assertNotNull(segment);
-        
+
         assertEquals("sample word document", p.getText(segment));
-        
+
         assertTrue(p.removeRun(0));
     }
-    
+
     @SuppressWarnings("deprecation")
     public void testRuns() {
         XWPFDocument doc = new XWPFDocument();
@@ -489,7 +505,7 @@
         XWPFRun r = new XWPFRun(run, doc.createParagraph());
         p.addRun(r);
         p.addRun(r);
-        
+
         assertNotNull(p.getRun(run));
         assertNull(p.getRun(null));
     }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
index 34a47fd..c9123a3 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
@@ -20,138 +20,129 @@
 import static org.junit.Assert.assertArrayEquals;
 
 import java.io.IOException;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.opc.PackageRelationship;
-import org.apache.poi.xssf.usermodel.XSSFRelation;
+import java.util.List;

+

+import junit.framework.TestCase;

+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

+import org.apache.poi.openxml4j.opc.PackageRelationship;

+import org.apache.poi.xssf.usermodel.XSSFRelation;

 import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
-
-public class TestXWPFPictureData extends TestCase {
-    
-    public void testRead() throws InvalidFormatException, IOException
-    {
-        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
-        List<XWPFPictureData> pictures = sampleDoc.getAllPictures();
-
-        assertEquals(5,pictures.size());
-        String[] ext = {"wmf","png","emf","emf","jpeg"};
-        for (int i = 0 ; i < pictures.size() ; i++)
-        {
-            assertEquals(ext[i],pictures.get(i).suggestFileExtension());
-        }
-
-        int num = pictures.size();
-
-        byte[] pictureData = XWPFTestDataSamples.getImage("nature1.jpg");
-
-        String relationId = sampleDoc.addPictureData(pictureData,XWPFDocument.PICTURE_TYPE_JPEG);
-        // picture list was updated
-        assertEquals(num + 1,pictures.size());
-        XWPFPictureData pict = (XWPFPictureData) sampleDoc.getRelationById(relationId);
-        assertEquals("jpeg",pict.suggestFileExtension());
-        assertArrayEquals(pictureData,pict.getData());
-    }
-
-    public void testPictureInHeader() throws IOException
-    {
-        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
-        verifyOneHeaderPicture(sampleDoc);
-        
-        XWPFDocument readBack = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc);
-        verifyOneHeaderPicture(readBack);
-    }
+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

+

+public class TestXWPFPictureData extends TestCase {

+

+    public void testRead() throws InvalidFormatException, IOException {

+        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");

+        List<XWPFPictureData> pictures = sampleDoc.getAllPictures();

+

+        assertEquals(5, pictures.size());

+        String[] ext = {"wmf", "png", "emf", "emf", "jpeg"};

+        for (int i = 0; i < pictures.size(); i++) {

+            assertEquals(ext[i], pictures.get(i).suggestFileExtension());

+        }

+

+        int num = pictures.size();

+

+        byte[] pictureData = XWPFTestDataSamples.getImage("nature1.jpg");

+

+        String relationId = sampleDoc.addPictureData(pictureData, XWPFDocument.PICTURE_TYPE_JPEG);

+        // picture list was updated

+        assertEquals(num + 1, pictures.size());

+        XWPFPictureData pict = (XWPFPictureData) sampleDoc.getRelationById(relationId);

+        assertEquals("jpeg", pict.suggestFileExtension());

+        assertArrayEquals(pictureData, pict.getData());

+    }

+

+    public void testPictureInHeader() throws IOException {

+        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");

+        verifyOneHeaderPicture(sampleDoc);

+

+        XWPFDocument readBack = XWPFTestDataSamples.writeOutAndReadBack(sampleDoc);

+        verifyOneHeaderPicture(readBack);

+    }

 
     private void verifyOneHeaderPicture(XWPFDocument sampleDoc) {
         XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
 
-        XWPFHeader header = policy.getDefaultHeader();
-
-        List<XWPFPictureData> pictures = header.getAllPictures();
-        assertEquals(1,pictures.size());
-    }
-
-    public void testNew() throws InvalidFormatException, IOException 
-    {
-        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx");
-        byte[] jpegData = XWPFTestDataSamples.getImage("nature1.jpg");
-        assertNotNull(jpegData);
+        XWPFHeader header = policy.getDefaultHeader();

+

+        List<XWPFPictureData> pictures = header.getAllPictures();

+        assertEquals(1, pictures.size());

+    }

+

+    public void testNew() throws InvalidFormatException, IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx");

+        byte[] jpegData = XWPFTestDataSamples.getImage("nature1.jpg");

+        assertNotNull(jpegData);

         byte[] gifData = XWPFTestDataSamples.getImage("nature1.gif");
         assertNotNull(gifData);
         byte[] pngData = XWPFTestDataSamples.getImage("nature1.png");
-        assertNotNull(pngData);
-
-        List<XWPFPictureData> pictures = doc.getAllPictures();
-        assertEquals(0,pictures.size());
-
-        // Document shouldn't have any image relationships
-        assertEquals(13,doc.getPackagePart().getRelationships().size());
-        for (PackageRelationship rel : doc.getPackagePart().getRelationships())
-        {
-            if (rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation()))
-            {
-                fail("Shouldn't have JPEG yet");
-            }
-        }
-
-        // Add the image
-        String relationId = doc.addPictureData(jpegData,XWPFDocument.PICTURE_TYPE_JPEG);
-        assertEquals(1,pictures.size());
-        XWPFPictureData jpgPicData = (XWPFPictureData) doc.getRelationById(relationId);
-        assertEquals("jpeg",jpgPicData.suggestFileExtension());
-        assertArrayEquals(jpegData,jpgPicData.getData());
-
-        // Ensure it now has one
-        assertEquals(14,doc.getPackagePart().getRelationships().size());
-        PackageRelationship jpegRel = null;
-        for (PackageRelationship rel : doc.getPackagePart().getRelationships())
-        {
-            if (rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation()))
-            {
-                if (jpegRel != null)
-                    fail("Found 2 jpegs!");
-                jpegRel = rel;
-            }
-        }
-        assertNotNull("JPEG Relationship not found",jpegRel);
-
-        // Check the details
-        assertNotNull(jpegRel);
-        assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(),jpegRel.getRelationshipType());
-        assertEquals("/word/document.xml",jpegRel.getSource().getPartName().toString());
-        assertEquals("/word/media/image1.jpeg",jpegRel.getTargetURI().getPath());
-
-        XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId());
-        assertArrayEquals(jpegData, pictureDataByID.getData());
-
-        // Save an re-load, check it appears
-        doc = XWPFTestDataSamples.writeOutAndReadBack(doc);
-        assertEquals(1,doc.getAllPictures().size());
-        assertEquals(1,doc.getAllPackagePictures().size());
-
-        // verify the picture that we read back in
-        pictureDataByID = doc.getPictureDataByID(jpegRel.getId());
-        assertArrayEquals(jpegData, pictureDataByID.getData());
-        
-    }
-
-    public void testBug51770() throws InvalidFormatException, IOException {
+        assertNotNull(pngData);

+

+        List<XWPFPictureData> pictures = doc.getAllPictures();

+        assertEquals(0, pictures.size());

+

+        // Document shouldn't have any image relationships

+        assertEquals(13, doc.getPackagePart().getRelationships().size());

+        for (PackageRelationship rel : doc.getPackagePart().getRelationships()) {

+            if (rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation())) {

+                fail("Shouldn't have JPEG yet");

+            }

+        }

+

+        // Add the image

+        String relationId = doc.addPictureData(jpegData, XWPFDocument.PICTURE_TYPE_JPEG);

+        assertEquals(1, pictures.size());

+        XWPFPictureData jpgPicData = (XWPFPictureData) doc.getRelationById(relationId);

+        assertEquals("jpeg", jpgPicData.suggestFileExtension());

+        assertArrayEquals(jpegData, jpgPicData.getData());

+

+        // Ensure it now has one

+        assertEquals(14, doc.getPackagePart().getRelationships().size());

+        PackageRelationship jpegRel = null;

+        for (PackageRelationship rel : doc.getPackagePart().getRelationships()) {

+            if (rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation())) {

+                if (jpegRel != null)

+                    fail("Found 2 jpegs!");

+                jpegRel = rel;

+            }

+        }

+        assertNotNull("JPEG Relationship not found", jpegRel);

+

+        // Check the details

+        assertNotNull(jpegRel);

+        assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(), jpegRel.getRelationshipType());

+        assertEquals("/word/document.xml", jpegRel.getSource().getPartName().toString());

+        assertEquals("/word/media/image1.jpeg", jpegRel.getTargetURI().getPath());

+

+        XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId());

+        assertArrayEquals(jpegData, pictureDataByID.getData());

+

+        // Save an re-load, check it appears

+        doc = XWPFTestDataSamples.writeOutAndReadBack(doc);

+        assertEquals(1, doc.getAllPictures().size());

+        assertEquals(1, doc.getAllPackagePictures().size());

+

+        // verify the picture that we read back in

+        pictureDataByID = doc.getPictureDataByID(jpegRel.getId());

+        assertArrayEquals(jpegData, pictureDataByID.getData());

+

+    }

+

+    public void testBug51770() throws InvalidFormatException, IOException {

         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug51170.docx");
         XWPFHeaderFooterPolicy policy = doc.getHeaderFooterPolicy();
         XWPFHeader header = policy.getDefaultHeader();
         for (XWPFParagraph paragraph : header.getParagraphs()) {
             for (XWPFRun run : paragraph.getRuns()) {
                 for (XWPFPicture picture : run.getEmbeddedPictures()) {
-                    if (paragraph.getDocument() != null) {
-                        //System.out.println(picture.getCTPicture());
-                        XWPFPictureData data = picture.getPictureData();
-                        if(data != null) System.out.println(data.getFileName());
-                    }
-                }
-            }
+                    if (paragraph.getDocument() != null) {

+                        //System.out.println(picture.getCTPicture());

+                        XWPFPictureData data = picture.getPictureData();

+                        if (data != null) System.out.println(data.getFileName());

+                    }

+                }

+            }

         }
 
     }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java
index 618618f..d9af8c9 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java
@@ -20,13 +20,12 @@
 import java.io.IOException;
 import java.math.BigInteger;
 import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
+import java.util.List;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;

 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrClear;
@@ -46,28 +45,28 @@
         p = doc.createParagraph();
 
         this.ctRun = CTR.Factory.newInstance();
-    }
-
-    public void testSetGetText() {
-        ctRun.addNewT().setStringValue("TEST STRING");	
-        ctRun.addNewT().setStringValue("TEST2 STRING");	
-        ctRun.addNewT().setStringValue("TEST3 STRING");
-
-        assertEquals(3,ctRun.sizeOfTArray());
-        XWPFRun run = new XWPFRun(ctRun, p);
-
-        assertEquals("TEST2 STRING",run.getText(1));
-
-        run.setText("NEW STRING",0);
-        assertEquals("NEW STRING",run.getText(0));
-
-        //run.setText("xxx",14);
-        //fail("Position wrong");
-    }
-  
-    public void testSetGetBold() {
-        CTRPr rpr = ctRun.addNewRPr();
-        rpr.addNewB().setVal(STOnOff.TRUE);
+    }

+

+    public void testSetGetText() {

+        ctRun.addNewT().setStringValue("TEST STRING");

+        ctRun.addNewT().setStringValue("TEST2 STRING");

+        ctRun.addNewT().setStringValue("TEST3 STRING");

+

+        assertEquals(3, ctRun.sizeOfTArray());

+        XWPFRun run = new XWPFRun(ctRun, p);

+

+        assertEquals("TEST2 STRING", run.getText(1));

+

+        run.setText("NEW STRING", 0);

+        assertEquals("NEW STRING", run.getText(0));

+

+        //run.setText("xxx",14);

+        //fail("Position wrong");

+    }

+

+    public void testSetGetBold() {

+        CTRPr rpr = ctRun.addNewRPr();

+        rpr.addNewB().setVal(STOnOff.TRUE);

 
         XWPFRun run = new XWPFRun(ctRun, p);
         assertEquals(true, run.isBold());
@@ -178,16 +177,16 @@
         run.setText("T1");
         run.addCarriageReturn();
         run.addCarriageReturn();
-        run.setText("T2");
-        run.addCarriageReturn();
-        assertEquals(3, run.getCTR().sizeOfCrArray());
-        
-        assertEquals("T1\n\nT2\n", run.toString());
-    }
-    
-    public void testAddTabsAndLineBreaks() {
-        ctRun.addNewT().setStringValue("TEST STRING");
-        ctRun.addNewCr();
+        run.setText("T2");

+        run.addCarriageReturn();

+        assertEquals(3, run.getCTR().sizeOfCrArray());

+

+        assertEquals("T1\n\nT2\n", run.toString());

+    }

+

+    public void testAddTabsAndLineBreaks() {

+        ctRun.addNewT().setStringValue("TEST STRING");

+        ctRun.addNewCr();

         ctRun.addNewT().setStringValue("TEST2 STRING");
         ctRun.addNewTab();
         ctRun.addNewT().setStringValue("TEST3 STRING");
@@ -199,21 +198,21 @@
         run.addCarriageReturn();
         run.setText("T2");
         run.addTab();
-        run.setText("T3");
-        assertEquals(1, run.getCTR().sizeOfCrArray());
-        assertEquals(1, run.getCTR().sizeOfTabArray());
-        
-        assertEquals("T1\nT2\tT3", run.toString());
-    }
-
+        run.setText("T3");

+        assertEquals(1, run.getCTR().sizeOfCrArray());

+        assertEquals(1, run.getCTR().sizeOfTabArray());

+

+        assertEquals("T1\nT2\tT3", run.toString());

+    }

+

     public void testAddPageBreak() {
-        ctRun.addNewT().setStringValue("TEST STRING");
-        ctRun.addNewBr();
-        ctRun.addNewT().setStringValue("TEST2 STRING");
-        CTBr breac=ctRun.addNewBr();
-        breac.setClear(STBrClear.LEFT);
-        ctRun.addNewT().setStringValue("TEST3 STRING");
-        assertEquals(2, ctRun.sizeOfBrArray());
+        ctRun.addNewT().setStringValue("TEST STRING");

+        ctRun.addNewBr();

+        ctRun.addNewT().setStringValue("TEST2 STRING");

+        CTBr breac = ctRun.addNewBr();

+        breac.setClear(STBrClear.LEFT);

+        ctRun.addNewT().setStringValue("TEST3 STRING");

+        assertEquals(2, ctRun.sizeOfBrArray());

 
         XWPFRun run = new XWPFRun(CTR.Factory.newInstance(), p);
         run.setText("TEXT1");
@@ -222,144 +221,145 @@
         run.addBreak(BreakType.TEXT_WRAPPING);
         assertEquals(2, run.getCTR().sizeOfBrArray());
     }
-
-    /**
-     * Test that on an existing document, we do the
-     *  right thing with it
-     * @throws IOException 
-     */
-    public void testExisting() throws IOException {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
-       XWPFParagraph p;
-       XWPFRun run;
-       
-       
-       // First paragraph is simple
-       p = doc.getParagraphArray(0);
-       assertEquals("This is a test document.", p.getText());
-       assertEquals(2, p.getRuns().size());
-       
-       run = p.getRuns().get(0);
-       assertEquals("This is a test document", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(1);
-       assertEquals(".", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       
-       // Next paragraph is all in one style, but a different one
-       p = doc.getParagraphArray(1);
-       assertEquals("This bit is in bold and italic", p.getText());
-       assertEquals(1, p.getRuns().size());
-       
-       run = p.getRuns().get(0);
-       assertEquals("This bit is in bold and italic", run.toString());
-       assertEquals(true, run.isBold());
-       assertEquals(true, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(true, run.getCTR().getRPr().isSetB());
-       assertEquals(false, run.getCTR().getRPr().getB().isSetVal());
-       
-       
-       // Back to normal
-       p = doc.getParagraphArray(2);
-       assertEquals("Back to normal", p.getText());
-       assertEquals(1, p.getRuns().size());
-       
-       run = p.getRuns().get(0);
-       assertEquals("Back to normal", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       
-       // Different styles in one paragraph
-       p = doc.getParagraphArray(3);
-       assertEquals("This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.", p.getText());
-       assertEquals(11, p.getRuns().size());
-       
-       run = p.getRuns().get(0);
-       assertEquals("This contains ", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(1);
-       assertEquals("BOLD", run.toString());
-       assertEquals(true, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       
-       run = p.getRuns().get(2);
-       assertEquals(", ", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(3);
-       assertEquals("ITALIC", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(true, run.isItalic());
-       assertEquals(false, run.isStrike());
-       
-       run = p.getRuns().get(4);
-       assertEquals(" and ", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(5);
-       assertEquals("BOTH", run.toString());
-       assertEquals(true, run.isBold());
-       assertEquals(true, run.isItalic());
-       assertEquals(false, run.isStrike());
-       
-       run = p.getRuns().get(6);
-       assertEquals(", as well as ", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(7);
-       assertEquals("RED", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       
-       run = p.getRuns().get(8);
-       assertEquals(" and ", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-       
-       run = p.getRuns().get(9);
-       assertEquals("YELLOW", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       
-       run = p.getRuns().get(10);
-       assertEquals(" text.", run.toString());
-       assertEquals(false, run.isBold());
-       assertEquals(false, run.isItalic());
-       assertEquals(false, run.isStrike());
-       assertEquals(null, run.getCTR().getRPr());
-    }
-
-    public void testPictureInHeader() throws IOException {
+

+    /**

+     * Test that on an existing document, we do the

+     * right thing with it

+     *

+     * @throws IOException

+     */

+    public void testExisting() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");

+        XWPFParagraph p;

+        XWPFRun run;

+

+

+        // First paragraph is simple

+        p = doc.getParagraphArray(0);

+        assertEquals("This is a test document.", p.getText());

+        assertEquals(2, p.getRuns().size());

+

+        run = p.getRuns().get(0);

+        assertEquals("This is a test document", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(1);

+        assertEquals(".", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+

+        // Next paragraph is all in one style, but a different one

+        p = doc.getParagraphArray(1);

+        assertEquals("This bit is in bold and italic", p.getText());

+        assertEquals(1, p.getRuns().size());

+

+        run = p.getRuns().get(0);

+        assertEquals("This bit is in bold and italic", run.toString());

+        assertEquals(true, run.isBold());

+        assertEquals(true, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(true, run.getCTR().getRPr().isSetB());

+        assertEquals(false, run.getCTR().getRPr().getB().isSetVal());

+

+

+        // Back to normal

+        p = doc.getParagraphArray(2);

+        assertEquals("Back to normal", p.getText());

+        assertEquals(1, p.getRuns().size());

+

+        run = p.getRuns().get(0);

+        assertEquals("Back to normal", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+

+        // Different styles in one paragraph

+        p = doc.getParagraphArray(3);

+        assertEquals("This contains BOLD, ITALIC and BOTH, as well as RED and YELLOW text.", p.getText());

+        assertEquals(11, p.getRuns().size());

+

+        run = p.getRuns().get(0);

+        assertEquals("This contains ", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(1);

+        assertEquals("BOLD", run.toString());

+        assertEquals(true, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+

+        run = p.getRuns().get(2);

+        assertEquals(", ", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(3);

+        assertEquals("ITALIC", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(true, run.isItalic());

+        assertEquals(false, run.isStrike());

+

+        run = p.getRuns().get(4);

+        assertEquals(" and ", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(5);

+        assertEquals("BOTH", run.toString());

+        assertEquals(true, run.isBold());

+        assertEquals(true, run.isItalic());

+        assertEquals(false, run.isStrike());

+

+        run = p.getRuns().get(6);

+        assertEquals(", as well as ", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(7);

+        assertEquals("RED", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+

+        run = p.getRuns().get(8);

+        assertEquals(" and ", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+

+        run = p.getRuns().get(9);

+        assertEquals("YELLOW", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+

+        run = p.getRuns().get(10);

+        assertEquals(" text.", run.toString());

+        assertEquals(false, run.isBold());

+        assertEquals(false, run.isItalic());

+        assertEquals(false, run.isStrike());

+        assertEquals(null, run.getCTR().getRPr());

+    }

+

+    public void testPictureInHeader() throws IOException {

         XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
         XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
 
@@ -373,47 +373,47 @@
 
                 for (XWPFPicture pic : pictures) {
                     assertNotNull(pic.getPictureData());
-                    assertEquals("DOZOR", pic.getDescription());
-                }
-
-                count+= pictures.size();
-            }
-        }
-
-        assertEquals(1, count);
-    }
-    
-    public void testAddPicture() throws Exception {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
-       XWPFParagraph p = doc.getParagraphArray(2);
-       XWPFRun r = p.getRuns().get(0);
-       
-       assertEquals(0, doc.getAllPictures().size());
-       assertEquals(0, r.getEmbeddedPictures().size());
-       
-       r.addPicture(new ByteArrayInputStream(new byte[0]), Document.PICTURE_TYPE_JPEG, "test.jpg", 21, 32);
-       
-       assertEquals(1, doc.getAllPictures().size());
-       assertEquals(1, r.getEmbeddedPictures().size());
-    }
-    
-    /**
-     * Bugzilla #52288 - setting the font family on the
-     *  run mustn't NPE
-     */
-    public void testSetFontFamily_52288() throws Exception {
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52288.docx");
-       final Iterator<XWPFParagraph> paragraphs = doc.getParagraphsIterator();
-       while (paragraphs.hasNext()) {
-          final XWPFParagraph paragraph = paragraphs.next();
-          for (final XWPFRun run : paragraph.getRuns()) {
-             if (run != null) {
-                final String text = run.getText(0);
-                if (text != null) {
-                   run.setFontFamily("Times New Roman");
-                }
-             }
-          }
-       }
-    }
-}
+                    assertEquals("DOZOR", pic.getDescription());

+                }

+

+                count += pictures.size();

+            }

+        }

+

+        assertEquals(1, count);

+    }

+

+    public void testAddPicture() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");

+        XWPFParagraph p = doc.getParagraphArray(2);

+        XWPFRun r = p.getRuns().get(0);

+

+        assertEquals(0, doc.getAllPictures().size());

+        assertEquals(0, r.getEmbeddedPictures().size());

+

+        r.addPicture(new ByteArrayInputStream(new byte[0]), Document.PICTURE_TYPE_JPEG, "test.jpg", 21, 32);

+

+        assertEquals(1, doc.getAllPictures().size());

+        assertEquals(1, r.getEmbeddedPictures().size());

+    }

+

+    /**

+     * Bugzilla #52288 - setting the font family on the

+     * run mustn't NPE

+     */

+    public void testSetFontFamily_52288() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52288.docx");

+        final Iterator<XWPFParagraph> paragraphs = doc.getParagraphsIterator();

+        while (paragraphs.hasNext()) {

+            final XWPFParagraph paragraph = paragraphs.next();

+            for (final XWPFRun run : paragraph.getRuns()) {

+                if (run != null) {

+                    final String text = run.getText(0);

+                    if (text != null) {

+                        run.setFontFamily("Times New Roman");

+                    }

+                }

+            }

+        }

+    }

+}

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java
index f4114c9..92c9405 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java
@@ -15,48 +15,46 @@
    limitations under the License.
 ==================================================================== */
 
-package org.apache.poi.xwpf.usermodel;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-
-public final class TestXWPFSDT extends TestCase {
-
-    /**
-     * Test simple tag and title extraction from SDT
-     * @throws Exception
-     */
-    public void testTagTitle() throws Exception {
-        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
-        String tag = null;
-        String title= null;
-        List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
-        for (AbstractXWPFSDT sdt :sdts){
-            if (sdt.getContent().toString().equals("Rich_text")){
-                tag = "MyTag";
-                title = "MyTitle";
-                break;
-            }
-            
-        }
-        assertEquals("controls size", 13, sdts.size());
-
+package org.apache.poi.xwpf.usermodel;

+

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Map;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+

+public final class TestXWPFSDT extends TestCase {

+

+    /**

+     * Test simple tag and title extraction from SDT

+     *

+     * @throws Exception

+     */

+    public void testTagTitle() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");

+        String tag = null;

+        String title = null;

+        List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);

+        for (AbstractXWPFSDT sdt : sdts) {

+            if (sdt.getContent().toString().equals("Rich_text")) {

+                tag = "MyTag";

+                title = "MyTitle";

+                break;

+            }

+

+        }

+        assertEquals("controls size", 13, sdts.size());

+

         assertEquals("tag", "MyTag", tag);
         assertEquals("title", "MyTitle", title);
-    }
-
-
-    public void testGetSDTs() throws Exception{
-        String[] contents = new String[]{
-                "header_rich_text",
-                "Rich_text",
+    }

+

+

+    public void testGetSDTs() throws Exception {

+        String[] contents = new String[]{

+                "header_rich_text",

+                "Rich_text",

                 "Rich_text_pre_table\nRich_text_cell1\t\t\t\n\t\t\t\n\t\t\t\n\nRich_text_post_table",
                 "Plain_text_no_newlines",
                 "Plain_text_with_newlines1\nplain_text_with_newlines2",
@@ -72,125 +70,126 @@
         };
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
         List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
-
-        assertEquals("number of sdts", contents.length, sdts.size());
-
-        for (int i = 0; i < contents.length; i++){
-            AbstractXWPFSDT sdt = sdts.get(i);
-            assertEquals(i+ ": " + contents[i], contents[i], sdt.getContent().toString());
-        } 
-    }
-    /**
-     * POI-54771 and TIKA-1317
-     */
+

+        assertEquals("number of sdts", contents.length, sdts.size());

+

+        for (int i = 0; i < contents.length; i++) {

+            AbstractXWPFSDT sdt = sdts.get(i);

+            assertEquals(i + ": " + contents[i], contents[i], sdt.getContent().toString());

+        }

+    }

+

+    /**

+     * POI-54771 and TIKA-1317

+     */

     public void testSDTAsCell() throws Exception {
         //Bug54771a.docx and Bug54771b.docx test slightly 
         //different recursion patterns. Keep both!
-        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54771a.docx");
-        List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
-        String text = sdts.get(0).getContent().getText();
-        assertEquals(2, sdts.size()); 
-        assertTrue(text.indexOf("Test") > -1);
-
-        text = sdts.get(1).getContent().getText();
+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54771a.docx");

+        List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);

+        String text = sdts.get(0).getContent().getText();

+        assertEquals(2, sdts.size());

+        assertTrue(text.indexOf("Test") > -1);

+

+        text = sdts.get(1).getContent().getText();

         assertTrue(text.indexOf("Test Subtitle") > -1);
         assertTrue(text.indexOf("Test User") > -1);
         assertTrue(text.indexOf("Test") < text.indexOf("Test Subtitle"));
-
-        doc = XWPFTestDataSamples.openSampleDocument("Bug54771b.docx");
-        sdts = extractAllSDTs(doc);
-        assertEquals(3, sdts.size()); 
-        assertTrue(sdts.get(0).getContent().getText().indexOf("Test") > -1);
-
-        assertTrue(sdts.get(1).getContent().getText().indexOf("Test Subtitle") > -1);
-        assertTrue(sdts.get(2).getContent().getText().indexOf("Test User") > -1);
-
-    }
-    
-    /**
-     * POI-55142 and Tika 1130
-     */
-    public void testNewLinesBetweenRuns() throws Exception{
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx");
-       List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
-       List<String> targs = new ArrayList<String>();
-       //these test newlines and tabs in paragraphs/body elements
-       targs.add("Rich-text1 abcdefghi");
-       targs.add("Rich-text2 abcd\t\tefgh");
-       targs.add("Rich-text3 abcd\nefg");
-       targs.add("Rich-text4 abcdefg");
-       targs.add("Rich-text5 abcdefg\nhijk");
-       targs.add("Plain-text1 abcdefg");
-       targs.add("Plain-text2 abcdefg\nhijk\nlmnop");
-       //this tests consecutive runs within a cell (not a paragraph)
-       //this test case was triggered by Tika-1130
-       targs.add("sdt_incell2 abcdefg");
-       
-       for (int i = 0; i < sdts.size(); i++){
-          AbstractXWPFSDT sdt = sdts.get(i);
-          assertEquals(targs.get(i), targs.get(i), sdt.getContent().getText());
-       }
-    }
-
-    private List<AbstractXWPFSDT> extractAllSDTs(XWPFDocument doc){
-        
-        List<AbstractXWPFSDT> sdts = new ArrayList<AbstractXWPFSDT>();
-
-        List<XWPFHeader> headers = doc.getHeaderList();
-        for (XWPFHeader header : headers){
-            sdts.addAll(extractSDTsFromBodyElements(header.getBodyElements()));
-        }
-        sdts.addAll(extractSDTsFromBodyElements(doc.getBodyElements()));
-
-        List<XWPFFooter> footers = doc.getFooterList();
-        for (XWPFFooter footer : footers){
-            sdts.addAll(extractSDTsFromBodyElements(footer.getBodyElements()));
-        }
-
-        for (XWPFFootnote footnote : doc.getFootnotes()){
-            sdts.addAll(extractSDTsFromBodyElements(footnote.getBodyElements()));
-        }
-        for (Map.Entry<Integer, XWPFFootnote> e : doc.endnotes.entrySet()){
-            sdts.addAll(extractSDTsFromBodyElements(e.getValue().getBodyElements()));
-        }
-        return sdts;
-    }
-
-    private List<AbstractXWPFSDT> extractSDTsFromBodyElements(List<IBodyElement> elements){
-        List<AbstractXWPFSDT> sdts = new ArrayList<AbstractXWPFSDT>();
-        for (IBodyElement e : elements){
-            if (e instanceof XWPFSDT){
-                XWPFSDT sdt = (XWPFSDT)e;
-                sdts.add(sdt);
-            } else if (e instanceof XWPFParagraph){
-
-                XWPFParagraph p = (XWPFParagraph)e;
-                for (IRunElement e2 : p.getIRuns()){
-                    if (e2 instanceof XWPFSDT){
-                        XWPFSDT sdt = (XWPFSDT)e2;
-                        sdts.add(sdt);
-                    }
-                }
-            } else if (e instanceof XWPFTable){
-                XWPFTable table = (XWPFTable)e;
-                sdts.addAll(extractSDTsFromTable(table));
-            }
-        }
+

+        doc = XWPFTestDataSamples.openSampleDocument("Bug54771b.docx");

+        sdts = extractAllSDTs(doc);

+        assertEquals(3, sdts.size());

+        assertTrue(sdts.get(0).getContent().getText().indexOf("Test") > -1);

+

+        assertTrue(sdts.get(1).getContent().getText().indexOf("Test Subtitle") > -1);

+        assertTrue(sdts.get(2).getContent().getText().indexOf("Test User") > -1);

+

+    }

+

+    /**

+     * POI-55142 and Tika 1130

+     */

+    public void testNewLinesBetweenRuns() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx");

+        List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);

+        List<String> targs = new ArrayList<String>();

+        //these test newlines and tabs in paragraphs/body elements

+        targs.add("Rich-text1 abcdefghi");

+        targs.add("Rich-text2 abcd\t\tefgh");

+        targs.add("Rich-text3 abcd\nefg");

+        targs.add("Rich-text4 abcdefg");

+        targs.add("Rich-text5 abcdefg\nhijk");

+        targs.add("Plain-text1 abcdefg");

+        targs.add("Plain-text2 abcdefg\nhijk\nlmnop");

+        //this tests consecutive runs within a cell (not a paragraph)

+        //this test case was triggered by Tika-1130

+        targs.add("sdt_incell2 abcdefg");

+

+        for (int i = 0; i < sdts.size(); i++) {

+            AbstractXWPFSDT sdt = sdts.get(i);

+            assertEquals(targs.get(i), targs.get(i), sdt.getContent().getText());

+        }

+    }

+

+    private List<AbstractXWPFSDT> extractAllSDTs(XWPFDocument doc) {

+

+        List<AbstractXWPFSDT> sdts = new ArrayList<AbstractXWPFSDT>();

+

+        List<XWPFHeader> headers = doc.getHeaderList();

+        for (XWPFHeader header : headers) {

+            sdts.addAll(extractSDTsFromBodyElements(header.getBodyElements()));

+        }

+        sdts.addAll(extractSDTsFromBodyElements(doc.getBodyElements()));

+

+        List<XWPFFooter> footers = doc.getFooterList();

+        for (XWPFFooter footer : footers) {

+            sdts.addAll(extractSDTsFromBodyElements(footer.getBodyElements()));

+        }

+

+        for (XWPFFootnote footnote : doc.getFootnotes()) {

+            sdts.addAll(extractSDTsFromBodyElements(footnote.getBodyElements()));

+        }

+        for (Map.Entry<Integer, XWPFFootnote> e : doc.endnotes.entrySet()) {

+            sdts.addAll(extractSDTsFromBodyElements(e.getValue().getBodyElements()));

+        }

+        return sdts;

+    }

+

+    private List<AbstractXWPFSDT> extractSDTsFromBodyElements(List<IBodyElement> elements) {

+        List<AbstractXWPFSDT> sdts = new ArrayList<AbstractXWPFSDT>();

+        for (IBodyElement e : elements) {

+            if (e instanceof XWPFSDT) {

+                XWPFSDT sdt = (XWPFSDT) e;

+                sdts.add(sdt);

+            } else if (e instanceof XWPFParagraph) {

+

+                XWPFParagraph p = (XWPFParagraph) e;

+                for (IRunElement e2 : p.getIRuns()) {

+                    if (e2 instanceof XWPFSDT) {

+                        XWPFSDT sdt = (XWPFSDT) e2;

+                        sdts.add(sdt);

+                    }

+                }

+            } else if (e instanceof XWPFTable) {

+                XWPFTable table = (XWPFTable) e;

+                sdts.addAll(extractSDTsFromTable(table));

+            }

+        }

         return sdts;
     }
 
     private List<AbstractXWPFSDT> extractSDTsFromTable(XWPFTable table) {
 
         List<AbstractXWPFSDT> sdts = new ArrayList<AbstractXWPFSDT>();
-        for (XWPFTableRow r : table.getRows()) {
-            for (ICell c : r.getTableICells()) {
-                if (c instanceof XWPFSDTCell) {
-                    sdts.add((XWPFSDTCell)c);
-                } else if (c instanceof XWPFTableCell) {
-                    sdts.addAll(extractSDTsFromBodyElements(((XWPFTableCell)c).getBodyElements()));
-                }
-            }
-        }
+        for (XWPFTableRow r : table.getRows()) {

+            for (ICell c : r.getTableICells()) {

+                if (c instanceof XWPFSDTCell) {

+                    sdts.add((XWPFSDTCell) c);

+                } else if (c instanceof XWPFTableCell) {

+                    sdts.addAll(extractSDTsFromBodyElements(((XWPFTableCell) c).getBodyElements()));

+                }

+            }

+        }

         return sdts;
     }
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java
index f12e168..0110927 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSmartTag.java
@@ -19,13 +19,12 @@
 import java.io.IOException;

 

 import junit.framework.TestCase;

-

 import org.apache.poi.xwpf.XWPFTestDataSamples;

 

 /**

  * Tests for reading SmartTags from Word docx.

  *

- * @author  Fabian Lange

+ * @author Fabian Lange

  */

 public final class TestXWPFSmartTag extends TestCase {

 

diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
index c29d502..bef00de 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
@@ -19,13 +19,12 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;
+import java.util.List;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;

 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
@@ -33,69 +32,69 @@
 
 public class TestXWPFStyles extends TestCase {
 
-//	protected void setUp() throws Exception {
-//		super.setUp();
-//	}
-	
-	public void testGetUsedStyles() throws IOException{
-		XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx");
-		List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>();
-		XWPFStyles styles = sampleDoc.getStyles();
-		XWPFStyle style = styles.getStyle("berschrift1");
-		testUsedStyleList.add(style);
-		testUsedStyleList.add(styles.getStyle("Standard"));
-		testUsedStyleList.add(styles.getStyle("berschrift1Zchn"));
-		testUsedStyleList.add(styles.getStyle("Absatz-Standardschriftart"));
-		style.hasSameName(style);
-		
-		List<XWPFStyle> usedStyleList = styles.getUsedStyleList(style);
-		assertEquals(usedStyleList, testUsedStyleList);
-		
-		
-	}
-
-	public void testAddStylesToDocument() throws IOException{
-		XWPFDocument docOut = new XWPFDocument();
-		XWPFStyles styles = docOut.createStyles();
-
-		String strStyleId = "headline1";
-		CTStyle ctStyle = CTStyle.Factory.newInstance();
-
-		ctStyle.setStyleId(strStyleId);
-		XWPFStyle s = new XWPFStyle(ctStyle);
-		styles.addStyle(s);
-		
-		assertTrue(styles.styleExist(strStyleId));
-
-    	XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);
-
-		styles = docIn.getStyles();
-		assertTrue(styles.styleExist(strStyleId));
-	}
-
-	/**
-	 * Bug #52449 - We should be able to write a file containing
-	 *  both regular and glossary styles without error
-	 */
-	public void test52449() throws Exception {
-      XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52449.docx");
-      XWPFStyles styles = doc.getStyles();
-      assertNotNull(styles);
-      
-      XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(doc);
-      styles = docIn.getStyles();
-      assertNotNull(styles);
-	}
-
-
-    /**
-     * YK: tests below don't make much sense,
-     * they exist only to copy xml beans to pi-ooxml-schemas.jar
-     */
-    public void testLanguages(){
-        XWPFDocument docOut = new XWPFDocument();
-        XWPFStyles styles = docOut.createStyles();
-        styles.setEastAsia("Chinese");
+//	protected void setUp() throws Exception {

+//		super.setUp();

+//	}

+

+    public void testGetUsedStyles() throws IOException {

+        XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx");

+        List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>();

+        XWPFStyles styles = sampleDoc.getStyles();

+        XWPFStyle style = styles.getStyle("berschrift1");

+        testUsedStyleList.add(style);

+        testUsedStyleList.add(styles.getStyle("Standard"));

+        testUsedStyleList.add(styles.getStyle("berschrift1Zchn"));

+        testUsedStyleList.add(styles.getStyle("Absatz-Standardschriftart"));

+        style.hasSameName(style);

+

+        List<XWPFStyle> usedStyleList = styles.getUsedStyleList(style);

+        assertEquals(usedStyleList, testUsedStyleList);

+

+

+    }

+

+    public void testAddStylesToDocument() throws IOException {

+        XWPFDocument docOut = new XWPFDocument();

+        XWPFStyles styles = docOut.createStyles();

+

+        String strStyleId = "headline1";

+        CTStyle ctStyle = CTStyle.Factory.newInstance();

+

+        ctStyle.setStyleId(strStyleId);

+        XWPFStyle s = new XWPFStyle(ctStyle);

+        styles.addStyle(s);

+

+        assertTrue(styles.styleExist(strStyleId));

+

+        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);

+

+        styles = docIn.getStyles();

+        assertTrue(styles.styleExist(strStyleId));

+    }

+

+    /**

+     * Bug #52449 - We should be able to write a file containing

+     * both regular and glossary styles without error

+     */

+    public void test52449() throws Exception {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("52449.docx");

+        XWPFStyles styles = doc.getStyles();

+        assertNotNull(styles);

+

+        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(doc);

+        styles = docIn.getStyles();

+        assertNotNull(styles);

+    }

+

+

+    /**

+     * YK: tests below don't make much sense,

+     * they exist only to copy xml beans to pi-ooxml-schemas.jar

+     */

+    public void testLanguages() {

+        XWPFDocument docOut = new XWPFDocument();

+        XWPFStyles styles = docOut.createStyles();

+        styles.setEastAsia("Chinese");

 
         styles.setSpellingLanguage("English");
 
@@ -116,26 +115,82 @@
         CTLsdException ex = latentStyles.addNewLsdException();
         ex.setName("ex1");
         XWPFLatentStyles ls = new XWPFLatentStyles(latentStyles);
-        assertEquals(true, ls.isLatentStyle("ex1"));
-        assertEquals(false, ls.isLatentStyle("notex1"));
-    }
-    
-    public void testSetStyles_Bug57254() throws IOException {
-        XWPFDocument docOut = new XWPFDocument();
-        XWPFStyles styles = docOut.createStyles();
+        assertEquals(true, ls.isLatentStyle("ex1"));

+        assertEquals(false, ls.isLatentStyle("notex1"));

+    }

+

+    public void testSetStyles_Bug57254() throws IOException {

+        XWPFDocument docOut = new XWPFDocument();

+        XWPFStyles styles = docOut.createStyles();

 
         CTStyles ctStyles = CTStyles.Factory.newInstance();
         String strStyleId = "headline1";
         CTStyle ctStyle = ctStyles.addNewStyle();
+

+        ctStyle.setStyleId(strStyleId);

+        styles.setStyles(ctStyles);

+

+        assertTrue(styles.styleExist(strStyleId));

+

+        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);

 
-        ctStyle.setStyleId(strStyleId);
-        styles.setStyles(ctStyles);
-        
-        assertTrue(styles.styleExist(strStyleId));
-
-        XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut);
-
-        styles = docIn.getStyles();
-        assertTrue(styles.styleExist(strStyleId));
-    }
+        styles = docIn.getStyles();

+        assertTrue(styles.styleExist(strStyleId));

+    }

+

+    public void testEasyAccessToStyles() throws IOException {

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");

+        XWPFStyles styles = doc.getStyles();

+        assertNotNull(styles);

+

+        // Has 3 paragraphs on page one, a break, and 3 on page 2

+        assertEquals(7, doc.getParagraphs().size());

+

+        // Check the first three have no run styles, just default paragraph style

+        for (int i = 0; i < 3; i++) {

+            XWPFParagraph p = doc.getParagraphs().get(i);

+            assertEquals(null, p.getStyle());

+            assertEquals(null, p.getStyleID());

+            assertEquals(1, p.getRuns().size());

+

+            XWPFRun r = p.getRuns().get(0);

+            assertEquals(null, r.getColor());

+            assertEquals(null, r.getFontFamily());

+            assertEquals(null, r.getFontName());

+            assertEquals(-1, r.getFontSize());

+        }

+

+        // On page two, has explicit styles, but on runs not on

+        //  the paragraph itself

+        for (int i = 4; i < 7; i++) {

+            XWPFParagraph p = doc.getParagraphs().get(i);

+            assertEquals(null, p.getStyle());

+            assertEquals(null, p.getStyleID());

+            assertEquals(1, p.getRuns().size());

+

+            XWPFRun r = p.getRuns().get(0);

+            assertEquals("Arial Black", r.getFontFamily());

+            assertEquals("Arial Black", r.getFontName());

+            assertEquals(16, r.getFontSize());

+            assertEquals("548DD4", r.getColor());

+        }

+

+        // Check the document styles

+        // Should have a style defined for each type

+        assertEquals(4, styles.getNumberOfStyles());

+        assertNotNull(styles.getStyle("Normal"));
+        assertNotNull(styles.getStyle("DefaultParagraphFont"));

+        assertNotNull(styles.getStyle("TableNormal"));

+        assertNotNull(styles.getStyle("NoList"));

+

+        // We can't do much yet with latent styles

+        assertEquals(137, styles.getLatentStyles().getNumberOfStyles());

+

+        // Check the default styles

+        assertNotNull(styles.getDefaultRunStyle());

+        assertNotNull(styles.getDefaultParagraphStyle());

+

+        assertEquals(11, styles.getDefaultRunStyle().getFontSize());

+        assertEquals(200, styles.getDefaultParagraphStyle().getSpacingAfter());

+    }

 }
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
index 00496b2..6f85a05 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
@@ -17,18 +17,18 @@
 package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.apache.poi.xwpf.usermodel.XWPFTable.XWPFBorderType;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import java.util.List;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.XWPFTestDataSamples;

+import org.apache.poi.xwpf.usermodel.XWPFTable.XWPFBorderType;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;

 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
@@ -64,6 +64,17 @@
         assertNotNull(ctTable.getTrArray(0).getTcArray(0).getPArray(0));
     }
 
+    public void testTblGrid() {
+        XWPFDocument doc = new XWPFDocument();
+        CTTbl ctTable = CTTbl.Factory.newInstance();
+        CTTblGrid cttblgrid = ctTable.addNewTblGrid();
+        cttblgrid.addNewGridCol().setW(new BigInteger("123"));
+        cttblgrid.addNewGridCol().setW(new BigInteger("321"));
+
+        XWPFTable xtab = new XWPFTable(ctTable, doc);
+        assertEquals(123, xtab.getCTTbl().getTblGrid().getGridColArray(0).getW().intValue());
+        assertEquals(321, xtab.getCTTbl().getTblGrid().getGridColArray(1).getW().intValue());
+    }
 
     public void testGetText() {
         XWPFDocument doc = new XWPFDocument();
@@ -110,13 +121,13 @@
         assertEquals(1, xtab.getCTTbl().getTrArray(0).sizeOfTcArray());
     }
 
-
-    public void testSetGetWidth() {
-        XWPFDocument doc = new XWPFDocument();
-        
-        CTTbl table = CTTbl.Factory.newInstance();
-        table.addNewTblPr().addNewTblW().setW(new BigInteger("1000"));
-
+

+    public void testSetGetWidth() {

+        XWPFDocument doc = new XWPFDocument();

+

+        CTTbl table = CTTbl.Factory.newInstance();

+        table.addNewTblPr().addNewTblW().setW(new BigInteger("1000"));

+

         XWPFTable xtab = new XWPFTable(table, doc);
 
         assertEquals(1000, xtab.getWidth());
@@ -134,20 +145,20 @@
         XWPFTableRow row = xtab.createRow();
         row.setHeight(20);
         assertEquals(20, row.getHeight());
-    }
-
-    public void testSetGetMargins() {
-    	// instantiate the following class so it'll get picked up by
-    	// the XmlBean process and added to the jar file. it's required
-    	// for the following XWPFTable methods.
-    	CTTblCellMar ctm = CTTblCellMar.Factory.newInstance();
-    	assertNotNull(ctm);
-    	// create a table
-        XWPFDocument doc = new XWPFDocument();
-    	CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
-        // set margins
-        table.setCellMargins(50, 50, 250, 450);
+    }

+

+    public void testSetGetMargins() {

+        // instantiate the following class so it'll get picked up by

+        // the XmlBean process and added to the jar file. it's required

+        // for the following XWPFTable methods.

+        CTTblCellMar ctm = CTTblCellMar.Factory.newInstance();

+        assertNotNull(ctm);

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // set margins

+        table.setCellMargins(50, 50, 250, 450);

         // get margin components
         int t = table.getCellMarginTop();
         assertEquals(50, t);
@@ -157,22 +168,22 @@
         assertEquals(250, b);
         int r = table.getCellMarginRight();
         assertEquals(450, r);
-    }
-
-    public void testSetGetHBorders() {
-    	// instantiate the following classes so they'll get picked up by
-    	// the XmlBean process and added to the jar file. they are required
-    	// for the following XWPFTable methods.
-    	CTTblBorders cttb = CTTblBorders.Factory.newInstance();
-    	assertNotNull(cttb);
-    	STBorder stb = STBorder.Factory.newInstance();
-    	assertNotNull(stb);
-    	// create a table
-        XWPFDocument doc = new XWPFDocument();
-    	CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
-        // set inside horizontal border
-        table.setInsideHBorder(XWPFBorderType.SINGLE, 4, 0, "FF0000");
+    }

+

+    public void testSetGetHBorders() {

+        // instantiate the following classes so they'll get picked up by

+        // the XmlBean process and added to the jar file. they are required

+        // for the following XWPFTable methods.

+        CTTblBorders cttb = CTTblBorders.Factory.newInstance();

+        assertNotNull(cttb);

+        STBorder stb = STBorder.Factory.newInstance();

+        assertNotNull(stb);

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // set inside horizontal border

+        table.setInsideHBorder(XWPFBorderType.SINGLE, 4, 0, "FF0000");

         // get inside horizontal border components
         int s = table.getInsideHBorderSize();
         assertEquals(4, s);
@@ -182,26 +193,26 @@
         assertEquals("FF0000", clr);
         XWPFBorderType bt = table.getInsideHBorderType();
         assertEquals(XWPFBorderType.SINGLE, bt);
-    }
-
-    public void testSetGetVBorders() {
-    	// create a table
-        XWPFDocument doc = new XWPFDocument();
-        CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
+    }

+

+    public void testSetGetVBorders() {

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

         // set inside vertical border
         table.setInsideVBorder(XWPFBorderType.DOUBLE, 4, 0, "00FF00");
         // get inside vertical border components
         XWPFBorderType bt = table.getInsideVBorderType();
         assertEquals(XWPFBorderType.DOUBLE, bt);
         int sz = table.getInsideVBorderSize();
-        assertEquals(4, sz);
-        int sp = table.getInsideVBorderSpace();
-        assertEquals(0, sp);
-        String clr =  table.getInsideVBorderColor();
-        assertEquals("00FF00", clr);
-    }
-
+        assertEquals(4, sz);

+        int sp = table.getInsideVBorderSpace();

+        assertEquals(0, sp);

+        String clr = table.getInsideVBorderColor();

+        assertEquals("00FF00", clr);

+    }

+

     public void testSetGetRowBandSize() {
         XWPFDocument doc = new XWPFDocument();
         CTTbl ctTable = CTTbl.Factory.newInstance();
@@ -218,32 +229,30 @@
         table.setColBandSize(16);
         int sz = table.getColBandSize();
         assertEquals(16, sz);
-    }
-
-    public void testCreateTable() throws Exception {
-       // open an empty document
-       XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
-
-       // create a table with 5 rows and 7 columns
-       int noRows = 5; 
-       int noCols = 7;
-       XWPFTable table = doc.createTable(noRows,noCols);
-
-       // assert the table is empty
-       List<XWPFTableRow> rows = table.getRows();
-       assertEquals("Table has less rows than requested.", noRows, rows.size());
-       for (XWPFTableRow xwpfRow : rows)
-       {
-          assertNotNull(xwpfRow);
-          for (int i = 0 ; i < 7 ; i++)
-          {
-             XWPFTableCell xwpfCell = xwpfRow.getCell(i);
-             assertNotNull(xwpfCell);
-             assertEquals("Empty cells should not have one paragraph.",1,xwpfCell.getParagraphs().size());
-             xwpfCell = xwpfRow.getCell(i);
-             assertEquals("Calling 'getCell' must not modify cells content.",1,xwpfCell.getParagraphs().size());
-          }
-       }
-       doc.getPackage().revert();
-    }
+    }

+

+    public void testCreateTable() throws Exception {

+        // open an empty document

+        XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");

+

+        // create a table with 5 rows and 7 columns

+        int noRows = 5;

+        int noCols = 7;

+        XWPFTable table = doc.createTable(noRows, noCols);

+

+        // assert the table is empty

+        List<XWPFTableRow> rows = table.getRows();

+        assertEquals("Table has less rows than requested.", noRows, rows.size());

+        for (XWPFTableRow xwpfRow : rows) {

+            assertNotNull(xwpfRow);

+            for (int i = 0; i < 7; i++) {

+                XWPFTableCell xwpfCell = xwpfRow.getCell(i);

+                assertNotNull(xwpfCell);

+                assertEquals("Empty cells should not have one paragraph.", 1, xwpfCell.getParagraphs().size());

+                xwpfCell = xwpfRow.getCell(i);

+                assertEquals("Calling 'getCell' must not modify cells content.", 1, xwpfCell.getParagraphs().size());

+            }

+        }

+        doc.getPackage().revert();

+    }

 }
\ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java
index 76dfe38..34d54c0 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java
@@ -17,71 +17,80 @@
  * ====================================================================
  */
 
-package org.apache.poi.xwpf.usermodel;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.xwpf.usermodel.XWPFTableCell.XWPFVertAlign;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
-
-public class TestXWPFTableCell extends TestCase {
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-	}
-
-	public void testSetGetVertAlignment() throws Exception {
-    	// instantiate the following classes so they'll get picked up by
-    	// the XmlBean process and added to the jar file. they are required
-    	// for the following XWPFTableCell methods.
-		CTShd ctShd = CTShd.Factory.newInstance();
-		assertNotNull(ctShd);
-		CTVerticalJc ctVjc = CTVerticalJc.Factory.newInstance();
-		assertNotNull(ctVjc);
-		STShd stShd = STShd.Factory.newInstance();
-		assertNotNull(stShd);
-		STVerticalJc stVjc = STVerticalJc.Factory.newInstance();
-		assertNotNull(stVjc);
-
-    	// create a table
-        XWPFDocument doc = new XWPFDocument();
-    	CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
-        // table has a single row by default; grab it
-        XWPFTableRow tr = table.getRow(0);
+package org.apache.poi.xwpf.usermodel;

+

+import junit.framework.TestCase;

+import org.apache.poi.xwpf.usermodel.XWPFTableCell.XWPFVertAlign;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STShd;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;

+

+public class TestXWPFTableCell extends TestCase {

+

+    @Override

+    protected void setUp() throws Exception {

+        super.setUp();

+    }

+

+    public void testSetGetVertAlignment() throws Exception {

+        // instantiate the following classes so they'll get picked up by

+        // the XmlBean process and added to the jar file. they are required

+        // for the following XWPFTableCell methods.

+        CTShd ctShd = CTShd.Factory.newInstance();

+        assertNotNull(ctShd);

+        CTVerticalJc ctVjc = CTVerticalJc.Factory.newInstance();

+        assertNotNull(ctVjc);

+        STShd stShd = STShd.Factory.newInstance();

+        assertNotNull(stShd);

+        STVerticalJc stVjc = STVerticalJc.Factory.newInstance();

+        assertNotNull(stVjc);

+

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // table has a single row by default; grab it

+        XWPFTableRow tr = table.getRow(0);

         assertNotNull(tr);
         // row has a single cell by default; grab it
         XWPFTableCell cell = tr.getCell(0);
 
-        cell.setVerticalAlignment(XWPFVertAlign.BOTH);
-        XWPFVertAlign al = cell.getVerticalAlignment();
-        assertEquals(XWPFVertAlign.BOTH, al);
-	}
-
-	public void testSetGetColor() throws Exception {
-    	// create a table
-        XWPFDocument doc = new XWPFDocument();
-    	CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
-        // table has a single row by default; grab it
-        XWPFTableRow tr = table.getRow(0);
+        cell.setVerticalAlignment(XWPFVertAlign.BOTH);

+        XWPFVertAlign al = cell.getVerticalAlignment();

+        assertEquals(XWPFVertAlign.BOTH, al);

+    }

+

+    public void testSetGetColor() throws Exception {

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // table has a single row by default; grab it

+        XWPFTableRow tr = table.getRow(0);

         assertNotNull(tr);
         // row has a single cell by default; grab it
         XWPFTableCell cell = tr.getCell(0);
 
-        cell.setColor("F0000F");
-        String clr = cell.getColor();
-        assertEquals("F0000F", clr);
-	}
-
-    /**
-     * ensure that CTHMerge & CTTcBorders go in poi-ooxml.jar
-     */
-	public void test54099(){
-        XWPFDocument doc = new XWPFDocument();
-        CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
+        cell.setColor("F0000F");

+        String clr = cell.getColor();

+        assertEquals("F0000F", clr);

+    }

+

+    /**

+     * ensure that CTHMerge & CTTcBorders go in poi-ooxml.jar

+     */

+    public void test54099() {

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

         XWPFTableRow tr = table.getRow(0);
         XWPFTableCell cell = tr.getCell(0);
 
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
index abdf168..b01f8e9 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
@@ -15,55 +15,54 @@
    limitations under the License.
 ==================================================================== */
 
-package org.apache.poi.xwpf.usermodel;
-
-import junit.framework.TestCase;
-
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
-
-public class TestXWPFTableRow extends TestCase {
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-	}
-
-	public void testCreateRow() throws Exception {
-		CTRow ctRow = CTRow.Factory.newInstance();
-		assertNotNull(ctRow);
-	}
-	
-	@Override
-	protected void tearDown() throws Exception {
-		super.tearDown();
-	}
-
-	public void testSetGetCantSplitRow() {
-            // create a table
-            XWPFDocument doc = new XWPFDocument();
-            CTTbl ctTable = CTTbl.Factory.newInstance();
-            XWPFTable table = new XWPFTable(ctTable, doc);
-            // table has a single row by default; grab it
-            XWPFTableRow tr = table.getRow(0);
-            assertNotNull(tr);
-
-            tr.setCantSplitRow(true);
-            boolean isCant = tr.isCantSplitRow();
-            assert(isCant);
-	}
-
-	public void testSetGetRepeatHeader() {
-        // create a table
-            XWPFDocument doc = new XWPFDocument();
-            CTTbl ctTable = CTTbl.Factory.newInstance();
-            XWPFTable table = new XWPFTable(ctTable, doc);
-            // table has a single row by default; grab it
-            XWPFTableRow tr = table.getRow(0);
-            assertNotNull(tr);
-
-            tr.setRepeatHeader(true);
-            boolean isRpt = tr.isRepeatHeader();
-            assert(isRpt);
-	}
-}
+package org.apache.poi.xwpf.usermodel;

+

+import junit.framework.TestCase;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;

+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;

+

+public class TestXWPFTableRow extends TestCase {

+

+    @Override

+    protected void setUp() throws Exception {

+        super.setUp();

+    }

+

+    public void testCreateRow() throws Exception {

+        CTRow ctRow = CTRow.Factory.newInstance();

+        assertNotNull(ctRow);

+    }

+

+    @Override

+    protected void tearDown() throws Exception {

+        super.tearDown();

+    }

+

+    public void testSetGetCantSplitRow() {

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // table has a single row by default; grab it

+        XWPFTableRow tr = table.getRow(0);

+        assertNotNull(tr);

+

+        tr.setCantSplitRow(true);

+        boolean isCant = tr.isCantSplitRow();

+        assert (isCant);

+    }

+

+    public void testSetGetRepeatHeader() {

+        // create a table

+        XWPFDocument doc = new XWPFDocument();

+        CTTbl ctTable = CTTbl.Factory.newInstance();

+        XWPFTable table = new XWPFTable(ctTable, doc);

+        // table has a single row by default; grab it

+        XWPFTableRow tr = table.getRow(0);

+        assertNotNull(tr);

+

+        tr.setRepeatHeader(true);

+        boolean isRpt = tr.isRepeatHeader();

+        assert (isRpt);

+    }

+}

diff --git a/src/scratchpad/src/org/apache/poi/hdf/event/EventBridge.java b/src/scratchpad/src/org/apache/poi/hdf/event/EventBridge.java
index d4f6947..c38805c 100644
--- a/src/scratchpad/src/org/apache/poi/hdf/event/EventBridge.java
+++ b/src/scratchpad/src/org/apache/poi/hdf/event/EventBridge.java
@@ -21,10 +21,10 @@
 import org.apache.poi.hdf.model.util.BTreeSet;
 import org.apache.poi.hdf.model.util.NumberFormatter;
 import org.apache.poi.hdf.model.hdftypes.*;
-
 import org.apache.poi.util.LittleEndian;
 
 import java.util.ArrayList;
+import java.util.List;
 
 @Deprecated
 public final class EventBridge implements HDFLowLevelParsingListener
@@ -71,11 +71,11 @@
   BTreeSet _hdrCharacterRuns = new BTreeSet();
 
   int _sectionCounter = 1;
-  ArrayList _hdrs = new ArrayList();
+  List<HeaderFooter[]> _hdrs = new ArrayList<HeaderFooter[]>();
 
   private boolean _holdParagraph = false;
   private int _endHoldIndex = -1;
-  private ArrayList _onHold;
+  private List<PropertyNode> _onHold;
 
   public EventBridge(HDFParsingListener listener)
   {
@@ -119,7 +119,7 @@
   {
     for (int x = 1; x < _sectionCounter; x++)
     {
-      HeaderFooter[] hdrArray = (HeaderFooter[])_hdrs.get(x-1);
+      HeaderFooter[] hdrArray = _hdrs.get(x-1);
       HeaderFooter hf = null;
 
       if (!hdrArray[HeaderFooter.HEADER_EVEN - 1].isEmpty())
@@ -210,7 +210,7 @@
         _holdParagraph = false;
         _endHoldIndex = -1;
         flushHeldParagraph();
-        _onHold = new ArrayList();
+        _onHold = new ArrayList<PropertyNode>();
       }
     }
 
@@ -219,7 +219,7 @@
 
     CharacterProperties chp = (CharacterProperties)StyleSheet.uncompressProperty(byteChpx, _currentStd.getCHP(), _stsh);
 
-    ArrayList textList = BTreeSet.findProperties(start, end, _text.root);
+    List<PropertyNode> textList = BTreeSet.findProperties(start, end, _text.root);
     String text = getTextFromNodes(textList, start, end);
 
     _listener.characterRun(chp, text, start - _fcMin, end - _fcMin);
@@ -241,7 +241,7 @@
   }
   private void flushHeaderProps(int start, int end)
   {
-    ArrayList list = BTreeSet.findProperties(start, end, _hdrSections.root);
+    List<PropertyNode> list = BTreeSet.findProperties(start, end, _hdrSections.root);
     int size = list.size();
 
     for (int x = 0; x < size; x++)
@@ -253,7 +253,7 @@
       //SepxNode node = new SepxNode(-1, secStart, secEnd, oldNode.getSepx());
       //bodySection(node);
 
-      ArrayList parList = BTreeSet.findProperties(secStart, secEnd, _hdrParagraphs.root);
+      List<PropertyNode> parList = BTreeSet.findProperties(secStart, secEnd, _hdrParagraphs.root);
       int parSize = parList.size();
 
       for (int y = 0; y < parSize; y++)
@@ -265,7 +265,7 @@
         PapxNode parNode = new PapxNode(parStart, parEnd, oldParNode.getPapx());
         paragraph(parNode);
 
-        ArrayList charList = BTreeSet.findProperties(parStart, parEnd, _hdrCharacterRuns.root);
+        List<PropertyNode> charList = BTreeSet.findProperties(parStart, parEnd, _hdrCharacterRuns.root);
         int charSize = charList.size();
 
         for (int z = 0; z < charSize; z++)
@@ -282,7 +282,7 @@
     }
 
   }
-  private String getTextFromNodes(ArrayList list, int start, int end)
+  private String getTextFromNodes(List<PropertyNode> list, int start, int end)
   {
     int size = list.size();
 
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java
index e8bc316..ff53300 100644
--- a/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java
+++ b/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java
@@ -114,6 +114,8 @@
   /**
    *  right now this function takes one parameter: a Word file, and outputs an
    *  XSL-FO document at c:\test.xml (this is hardcoded)
+   *  
+   *  @param args The document to read
    */
   public static void main(String args[])
   {
@@ -175,7 +177,7 @@
       }
       else
       {
-	String sText = new String(_header, start, end-start);
+	String sText = new String(_header, start, end-start, "windows-1252");
 	out.write(sText);
       }
     }
@@ -758,7 +760,7 @@
     size = lineHeights.size();
     for(int x = 0; x < size; x++)
     {
-      Integer height = (Integer)lineHeights.get(x);
+      Integer height = lineHeights.get(x);
       sum += height.intValue();
     }
 
@@ -1765,7 +1767,7 @@
       for(int x = 0; x < size; x++)
       {
         StringBuffer rowBuffer = tableBodyBuffer;
-        TableRow row = (TableRow)_table.get(x);
+        TableRow row = _table.get(x);
         TAP tap = row.getTAP();
         ArrayList<String> cells = row.getCells();
 
@@ -1797,7 +1799,7 @@
           addBorder(rowBuffer, tc._brcBottom, "bottom");
           addBorder(rowBuffer, tc._brcRight, "right");
           rowBuffer.append(">");
-          rowBuffer.append((String)cells.get(y));
+          rowBuffer.append(cells.get(y));
           rowBuffer.append("</fo:table-cell>");
         }
         rowBuffer.append("</fo:table-row>");
diff --git a/src/scratchpad/src/org/apache/poi/hdf/model/util/BTreeSet.java b/src/scratchpad/src/org/apache/poi/hdf/model/util/BTreeSet.java
index 848e74a..96cc51d 100644
--- a/src/scratchpad/src/org/apache/poi/hdf/model/util/BTreeSet.java
+++ b/src/scratchpad/src/org/apache/poi/hdf/model/util/BTreeSet.java
@@ -36,14 +36,14 @@
  *
 */
 @Deprecated
-public final class BTreeSet extends AbstractSet
+public final class BTreeSet extends AbstractSet<PropertyNode>
 {
 
     /*
      * Instance Variables
     */
     public BTreeNode root;
-    private Comparator comparator = null;
+    private Comparator<PropertyNode> comparator = null;
     private int order;
     int size = 0;
 
@@ -59,7 +59,7 @@
         this(6);           // Default order for a BTreeSet is 32
     }
 
-    public BTreeSet(Collection c)
+    public BTreeSet(Collection<PropertyNode> c)
     {
         this(6);           // Default order for a BTreeSet is 32
         addAll(c);
@@ -70,7 +70,7 @@
         this(order, null);
     }
 
-    public BTreeSet(int order, Comparator comparator)
+    public BTreeSet(int order, Comparator<PropertyNode> comparator)
     {
         this.order = order;
         this.comparator = comparator;
@@ -81,18 +81,18 @@
     /*
      * Public Methods
     */
-    public boolean add(Object x) throws IllegalArgumentException
+    public boolean add(PropertyNode x) throws IllegalArgumentException
     {
         if (x == null) throw new IllegalArgumentException();
         return root.insert(x, -1);
     }
 
-    public boolean contains(Object x)
+    public boolean contains(PropertyNode x)
     {
         return root.includes(x);
     }
 
-    public boolean remove(Object x)
+    public boolean remove(PropertyNode x)
     {
         if (x == null) return false;
         return root.delete(x, -1);
@@ -109,14 +109,14 @@
         size = 0;
     }
 
-    public java.util.Iterator iterator()
+	public java.util.Iterator<PropertyNode> iterator()
     {
         return new Iterator();
     }
 
-    public static ArrayList findProperties(int start, int end, BTreeSet.BTreeNode root)
+    public static List<PropertyNode> findProperties(int start, int end, BTreeSet.BTreeNode root)
     {
-      ArrayList results = new ArrayList();
+      List<PropertyNode> results = new ArrayList<PropertyNode>();
       BTreeSet.Entry[] entries = root.entries;
 
       for(int x = 0; x < entries.length; x++)
@@ -124,7 +124,7 @@
         if(entries[x] != null)
         {
           BTreeSet.BTreeNode child = entries[x].child;
-          PropertyNode xNode = (PropertyNode)entries[x].element;
+          PropertyNode xNode = entries[x].element;
           if(xNode != null)
           {
             int xStart = xNode.getStart();
@@ -135,7 +135,7 @@
               {
                 if(child != null)
                 {
-                  ArrayList beforeItems = findProperties(start, end, child);
+                  List<PropertyNode> beforeItems = findProperties(start, end, child);
                   results.addAll(beforeItems);
                 }
                 results.add(xNode);
@@ -150,7 +150,7 @@
             {
               if(child != null)
               {
-                ArrayList beforeItems = findProperties(start, end, child);
+                List<PropertyNode> beforeItems = findProperties(start, end, child);
                 results.addAll(beforeItems);
               }
               break;
@@ -158,7 +158,7 @@
           }
           else if(child != null)
           {
-            ArrayList afterItems = findProperties(start, end, child);
+            List<PropertyNode> afterItems = findProperties(start, end, child);
             results.addAll(afterItems);
           }
         }
@@ -172,9 +172,9 @@
     /*
      * Private methods
     */
-    int compare(Object x, Object y)
+    int compare(PropertyNode x, PropertyNode y)
     {
-        return (comparator == null ? ((Comparable)x).compareTo(y) : comparator.compare(x, y));
+        return (comparator == null ? x.compareTo(y) : comparator.compare(x, y));
     }
 
 
@@ -192,12 +192,12 @@
      * chance of receiving a NullPointerException. The Iterator.delete method is supported.
     */
 
-    private class Iterator implements java.util.Iterator
+    private class Iterator implements java.util.Iterator<PropertyNode>
     {
         private int index = 0;
-        private Stack parentIndex = new Stack(); // Contains all parentIndicies for currentNode
-        private Object lastReturned = null;
-        private Object next;
+        private Stack<Integer> parentIndex = new Stack<Integer>(); // Contains all parentIndicies for currentNode
+        private PropertyNode lastReturned = null;
+        private PropertyNode next;
         private BTreeNode currentNode;
 
         Iterator()
@@ -211,7 +211,7 @@
             return next != null;
         }
 
-        public Object next()
+        public PropertyNode next()
         {
             if (next == null) throw new NoSuchElementException();
 
@@ -241,7 +241,7 @@
             return temp;
         }
 
-        private Object nextElement()
+        private PropertyNode nextElement()
         {
             if (currentNode.isLeaf())
             {
@@ -250,13 +250,13 @@
                 else if (!parentIndex.empty())
                 { //All elements have been returned, return successor of lastReturned if it exists
                     currentNode = currentNode.parent;
-                    index = ((Integer)parentIndex.pop()).intValue();
+                    index = parentIndex.pop().intValue();
 
                     while (index == currentNode.nrElements)
                     {
                         if (parentIndex.empty()) break;
                         currentNode = currentNode.parent;
-                        index = ((Integer)parentIndex.pop()).intValue();
+                        index = parentIndex.pop().intValue();
                     }
 
                     if (index == currentNode.nrElements) return null; //Reached root and he has no more children
@@ -289,7 +289,7 @@
     public static class Entry
     {
 
-        public Object element;
+        public PropertyNode element;
         public BTreeNode child;
     }
 
@@ -309,11 +309,11 @@
             entries[0] = new Entry();
         }
 
-        boolean insert(Object x, int parentIndex)
+        boolean insert(PropertyNode x, int parentIndex)
         {
             if (isFull())
             { // If full, you must split and promote splitNode before inserting
-                Object splitNode = entries[nrElements / 2].element;
+            	PropertyNode splitNode = entries[nrElements / 2].element;
                 BTreeNode rightSibling = split();
 
                 if (isRoot())
@@ -354,7 +354,7 @@
             return false;
         }
 
-        boolean includes(Object x)
+        boolean includes(PropertyNode x)
         {
             int index = childToInsertAt(x, true);
             if (index == -1) return true;
@@ -362,7 +362,7 @@
             return entries[index].child.includes(x);
         }
 
-        boolean delete(Object x, int parentIndex)
+        boolean delete(PropertyNode x, int parentIndex)
         {
             int i = childToInsertAt(x, true);
             int priorParentIndex = parentIndex;
@@ -438,7 +438,7 @@
          * Creates a new BTreeSet.root which contains only the splitNode and pointers
          * to it's left and right child.
         */
-        private void splitRoot(Object splitNode, BTreeNode left, BTreeNode right)
+        private void splitRoot(PropertyNode splitNode, BTreeNode left, BTreeNode right)
         {
             BTreeNode newRoot = new BTreeNode(null);
             newRoot.entries[0].element = splitNode;
@@ -450,7 +450,7 @@
             BTreeSet.this.root = newRoot;
         }
 
-        private void insertSplitNode(Object splitNode, BTreeNode left, BTreeNode right, int insertAt)
+        private void insertSplitNode(PropertyNode splitNode, BTreeNode left, BTreeNode right, int insertAt)
         {
             for (int i = nrElements; i >= insertAt; i--) entries[i + 1] = entries[i];
 
@@ -462,7 +462,7 @@
             nrElements++;
         }
 
-        private void insertNewElement(Object x, int insertAt)
+        private void insertNewElement(PropertyNode x, int insertAt)
         {
 
             for (int i = nrElements; i > insertAt; i--) entries[i] = entries[i - 1];
@@ -482,7 +482,7 @@
          * element is contained in the calling BTreeNode than the position of the element
          * in entries[] is returned.
         */
-        private int childToInsertAt(Object x, boolean position)
+        private int childToInsertAt(PropertyNode x, boolean position)
         {
             int index = nrElements / 2;
 
@@ -509,7 +509,7 @@
         }
 
 
-        private void deleteElement(Object x)
+        private void deleteElement(PropertyNode x)
         {
             int index = childToInsertAt(x, false);
             for (; index < (nrElements - 1); index++) entries[index] = entries[index + 1];
@@ -568,12 +568,12 @@
             }
         }
 
-        private void switchWithSuccessor(Object x)
+        private void switchWithSuccessor(PropertyNode x)
         {
             int index = childToInsertAt(x, false);
             BTreeNode temp = entries[index + 1].child;
             while (temp.entries[0] != null && temp.entries[0].child != null) temp = temp.entries[0].child;
-            Object successor = temp.entries[0].element;
+            PropertyNode successor = temp.entries[0].element;
             temp.entries[0].element = entries[index].element;
             entries[index].element = successor;
         }
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java b/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java
index ed5e700..40a8a7b 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hdgf.dev;
 
-import java.io.FileInputStream;
+import java.io.File;
 
 import org.apache.poi.hdgf.HDGFDiagram;
 import org.apache.poi.hdgf.chunks.Chunk;
@@ -26,7 +26,7 @@
 import org.apache.poi.hdgf.streams.ChunkStream;
 import org.apache.poi.hdgf.streams.PointerContainingStream;
 import org.apache.poi.hdgf.streams.Stream;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 
 /**
  * Developer helper class to dump out the pointer+stream structure
@@ -41,7 +41,7 @@
 		}
 
 		HDGFDiagram hdgf = new HDGFDiagram(
-				new POIFSFileSystem(new FileInputStream(args[0]))
+				new NPOIFSFileSystem(new File(args[0]))
 		);
 
 		System.out.println("Opened " + args[0]);
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java b/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java
index 0290d59..d37a28e 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/extractor/VisioTextExtractor.java
@@ -62,7 +62,7 @@
 		this(new HDGFDiagram(dir, fs));
 	}
 	public VisioTextExtractor(InputStream inp) throws IOException {
-		this(new POIFSFileSystem(inp));
+		this(new NPOIFSFileSystem(inp));
 	}
 
 	/**
diff --git a/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java b/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java
index 332a496..f591d5a 100644
--- a/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java
@@ -22,6 +22,7 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import org.apache.poi.hmef.Attachment;
 import org.apache.poi.hmef.HMEFMessage;
@@ -70,13 +71,14 @@
     * Extracts the RTF message body to the supplied file
     */
    public void extractMessageBody(File dest) throws IOException {
-      FileOutputStream fout = new FileOutputStream(dest);
-      
-      MAPIRtfAttribute body = (MAPIRtfAttribute)
-         message.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED);
-      fout.write(body.getData());
-      
-      fout.close();
+      OutputStream fout = new FileOutputStream(dest);
+      try {
+          MAPIRtfAttribute body = (MAPIRtfAttribute)
+             message.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED);
+          fout.write(body.getData());
+      } finally {
+    	  fout.close();
+      }
    }
    
    /**
@@ -101,9 +103,12 @@
          
          // Save it
          File file = new File(dir, filename);
-         FileOutputStream fout = new FileOutputStream(file);
-         fout.write( att.getContents() );
-         fout.close();
+         OutputStream fout = new FileOutputStream(file);
+         try {
+        	 fout.write( att.getContents() );
+         } finally {
+        	 fout.close();
+         }
       }
    }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java b/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java
index 69602e7..fb046c8 100644
--- a/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java
+++ b/src/scratchpad/src/org/apache/poi/hpbf/HPBFDocument.java
@@ -51,21 +51,12 @@
 	   this(fs.getRoot());
 	}
 	public HPBFDocument(InputStream inp) throws IOException {
-	   this(new POIFSFileSystem(inp));
+	   this(new NPOIFSFileSystem(inp));
 	}
 
 	/**
 	 * Opens an embedded publisher document,
 	 *  at the given directory.
-	 * @deprecated Use {@link #HPBFDocument(DirectoryNode)} instead
-	 */
-	@Deprecated
-	public HPBFDocument(DirectoryNode dir, POIFSFileSystem fs) throws IOException {
-	   this(dir);
-	}
-	/**
-	 * Opens an embedded publisher document,
-	 *  at the given directory.
 	 */
 	public HPBFDocument(DirectoryNode dir) throws IOException {
 	   super(dir);
diff --git a/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java b/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java
index df4bb15..3ea5e9a 100644
--- a/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java
+++ b/src/scratchpad/src/org/apache/poi/hpbf/dev/HPBFDumper.java
@@ -25,7 +25,7 @@
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
 
@@ -35,12 +35,12 @@
  *  constructed.
  */
 public final class HPBFDumper {
-	private POIFSFileSystem fs;
-	public HPBFDumper(POIFSFileSystem fs) {
+	private NPOIFSFileSystem fs;
+	public HPBFDumper(NPOIFSFileSystem fs) {
 		this.fs = fs;
 	}
 	public HPBFDumper(InputStream inp) throws IOException {
-		this(new POIFSFileSystem(inp));
+		this(new NPOIFSFileSystem(inp));
 	}
 
 	private static byte[] getData(DirectoryNode dir, String name) throws IOException {
diff --git a/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java b/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java
index c6bfca9..7625a08 100644
--- a/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java
+++ b/src/scratchpad/src/org/apache/poi/hpbf/dev/PLCDumper.java
@@ -24,7 +24,7 @@
 import org.apache.poi.hpbf.HPBFDocument;
 import org.apache.poi.hpbf.model.QuillContents;
 import org.apache.poi.hpbf.model.qcbits.QCBit;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.util.HexDump;
 
 /**
@@ -40,11 +40,11 @@
 		doc = hpbfDoc;
 		qc = doc.getQuillContents();
 	}
-	public PLCDumper(POIFSFileSystem fs) throws IOException {
+	public PLCDumper(NPOIFSFileSystem fs) throws IOException {
 		this(new HPBFDocument(fs));
 	}
 	public PLCDumper(InputStream inp) throws IOException {
-		this(new POIFSFileSystem(inp));
+		this(new NPOIFSFileSystem(inp));
 	}
 
 	public static void main(String[] args) throws Exception {
diff --git a/src/scratchpad/src/org/apache/poi/hpbf/extractor/PublisherTextExtractor.java b/src/scratchpad/src/org/apache/poi/hpbf/extractor/PublisherTextExtractor.java
index be238b6..2295f23 100644
--- a/src/scratchpad/src/org/apache/poi/hpbf/extractor/PublisherTextExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hpbf/extractor/PublisherTextExtractor.java
@@ -53,10 +53,6 @@
    public PublisherTextExtractor(InputStream is) throws IOException {
       this(new POIFSFileSystem(is));
    }
-   @Deprecated
-   public PublisherTextExtractor(DirectoryNode dir, POIFSFileSystem fs) throws IOException {
-      this(new HPBFDocument(dir, fs));
-   }
 
 	/**
 	 * Should a call to getText() return hyperlinks inline
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java b/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
index 4c9e9ce..9755d46 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
@@ -32,15 +32,18 @@
 
     public byte[] getData(){
         byte[] rawdata = getRawData();
-        byte[] imgdata = new byte[rawdata.length-17];
-        System.arraycopy(rawdata, 17, imgdata, 0, imgdata.length);
+        int prefixLen = 16*uidInstanceCount+1;
+        byte[] imgdata = new byte[rawdata.length-prefixLen];
+        System.arraycopy(rawdata, prefixLen, imgdata, 0, imgdata.length);
         return imgdata;
     }
 
     public void setData(byte[] data) throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        byte[] checksum = getChecksum(data);
-        out.write(checksum);
+        for (int i=0; i<uidInstanceCount; i++) {
+            byte[] checksum = getChecksum(data);
+            out.write(checksum);
+        }
         out.write(0);
         out.write(data);
 
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java b/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java
index 5eb8149..e49fb16 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java
@@ -31,7 +31,7 @@
     /**
      * Size of the BITMAPFILEHEADER structure preceding the actual DIB bytes
      */
-    public static final int HEADER_SIZE = 14;
+    private static final int HEADER_SIZE = 14;
 
     /**
      * @return type of  this picture
@@ -42,13 +42,29 @@
     }
 
     /**
-     * DIB signature is <code>0x7A80</code>
+     * DIB signature is {@code 0x7A80} or {@code 0x7A90}
      *
-     * @return DIB signature (<code>0x7A80</code>)
+     * @return DIB signature ({@code 0x7A80} or {@code 0x7A90})
      */
     public int getSignature(){
-        return 0x7A80;
+        return (uidInstanceCount == 1 ? 0x7A80 : 0x7A90);
     }
+
+    /**
+     * Sets the DIB signature - either {@code 0x7A80} or {@code 0x7A90}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x7A80:
+                uidInstanceCount = 1;
+                break;
+            case 0x7A90:
+                uidInstanceCount = 2;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for DIB");
+        }        
+    }    
     
     public byte[] getData(){
         return addBMPHeader ( super.getData() );
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
index d7dadb6..5d3a45e 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
@@ -84,12 +84,28 @@
     }
 
     /**
-     * EMF signature is <code>0x3D40</code>
+     * EMF signature is {@code 0x3D40} or {@code 0x3D50}
      *
-     * @return EMF signature (<code>0x3D40</code>)
+     * @return EMF signature ({@code 0x3D40} or {@code 0x3D50})
      */
     public int getSignature(){
-        return 0x3D40;
+        return (uidInstanceCount == 1 ? 0x3D40 : 0x3D50);
+    }
+    
+    /**
+     * Sets the EMF signature - either {@code 0x3D40} or {@code 0x3D50}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x3D40:
+                uidInstanceCount = 1;
+                break;
+            case 0x3D50:
+                uidInstanceCount = 2;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for EMF");
+        }        
     }
 
     public String getContentType() {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java b/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
index 08ba5ce..ed436be 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
@@ -26,6 +26,10 @@
  */
 public final class JPEG extends Bitmap {
 
+    public enum ColorSpace { rgb, cymk };
+    
+    private ColorSpace colorSpace = ColorSpace.rgb;
+    
     /**
      * @return type of  this picture
      * @see  org.apache.poi.hslf.usermodel.HSLFPictureShape#JPEG
@@ -34,13 +38,49 @@
         return HSLFPictureShape.JPEG;
     }
 
+    public ColorSpace getColorSpace() {
+        return colorSpace;
+    }
+    
+    public void setColorSpace(ColorSpace colorSpace) {
+        this.colorSpace = colorSpace;
+    }
+    
     /**
-     * JPEG signature is <code>0x46A0</code>
+     * JPEG signature is one of {@code 0x46A0, 0x46B0, 0x6E20, 0x6E30} 
      *
-     * @return JPEG signature (<code>0x46A0</code>)
+     * @return JPEG signature ({@code 0x46A0, 0x46B0, 0x6E20, 0x6E30})
      */
     public int getSignature(){
-        return 0x46A0;
+        return (colorSpace == ColorSpace.rgb)
+            ? (uidInstanceCount == 1 ? 0x46A0 :  0x46B0)
+            : (uidInstanceCount == 1 ? 0x6E20 :  0x6E30);
+    }
+    
+    /**
+     * Sets the PICT signature - either {@code 0x5420} or {@code 0x5430}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x46A0:
+                uidInstanceCount = 1;
+                colorSpace = ColorSpace.rgb;
+                break;
+            case 0x46B0:
+                uidInstanceCount = 2;
+                colorSpace = ColorSpace.rgb;
+                break;
+            case 0x6E20:
+                uidInstanceCount = 1;
+                colorSpace = ColorSpace.cymk;
+                break;
+            case 0x6E30:
+                uidInstanceCount = 2;
+                colorSpace = ColorSpace.cymk;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for JPEG");
+        }        
     }
 
     public String getContentType() {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java b/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
index 535e206..b9f66ff 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
@@ -86,8 +86,8 @@
 
             zipsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
 
-            compression = LittleEndian.getUnsignedByte(data, pos); pos++;
-            filter = LittleEndian.getUnsignedByte(data, pos); pos++;
+            compression = LittleEndian.getUByte(data, pos); pos++;
+            filter = LittleEndian.getUByte(data, pos); pos++;
         }
 
         public void write(OutputStream out) throws IOException {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
index 016c50f..bebbcf4 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
@@ -33,10 +33,6 @@
  */
 public final class PICT extends Metafile {
 
-    public PICT(){
-        super();
-    }
-
     /**
      * Extract compressed PICT data from a ppt
      */
@@ -46,7 +42,7 @@
             byte[] macheader = new byte[512];
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             out.write(macheader);
-            int pos = CHECKSUM_SIZE;
+            int pos = CHECKSUM_SIZE*uidInstanceCount;
             byte[] pict;
             try {
                 pict = read(rawdata, pos);
@@ -109,12 +105,28 @@
     }
 
     /**
-     * PICT signature is <code>0x5430</code>
+     * PICT signature is {@code 0x5420} or {@code 0x5430}
      *
-     * @return PICT signature (<code>0x5430</code>)
+     * @return PICT signature ({@code 0x5420} or {@code 0x5430})
      */
     public int getSignature(){
-        return 0x5430;
+        return (uidInstanceCount == 1 ? 0x5420 : 0x5430);
+    }
+
+    /**
+     * Sets the PICT signature - either {@code 0x5420} or {@code 0x5430}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x5420:
+                uidInstanceCount = 1;
+                break;
+            case 0x5430:
+                uidInstanceCount = 2;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PICT");
+        }        
     }
 
     public String getContentType() {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java b/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
index 114b736..cd61a9b 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
@@ -53,12 +53,28 @@
     }
 
     /**
-     * PNG signature is <code>0x6E00</code>
+     * PNG signature is {@code 0x6E00} or {@code 0x6E10}
      *
-     * @return PNG signature (<code>0x6E00</code>)
+     * @return PNG signature ({@code 0x6E00} or {@code 0x6E10})
      */
     public int getSignature(){
-        return 0x6E00;
+        return (uidInstanceCount == 1 ? 0x6E00 : 0x6E10);
+    }
+    
+    /**
+     * Sets the PNG signature - either {@code 0x6E00} or {@code 0x6E10}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x6E00:
+                uidInstanceCount = 1;
+                break;
+            case 0x6E10:
+                uidInstanceCount = 2;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PNG");
+        }        
     }
 
     public String getContentType() {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
index a84aed2..e4f3b39 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
@@ -43,8 +43,8 @@
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             InputStream is = new ByteArrayInputStream( rawdata );
             Header header = new Header();
-            header.read(rawdata, CHECKSUM_SIZE);
-            is.skip(header.getSize() + CHECKSUM_SIZE);
+            header.read(rawdata, CHECKSUM_SIZE*uidInstanceCount);
+            is.skip(header.getSize() + CHECKSUM_SIZE*uidInstanceCount);
 
             AldusHeader aldus = new AldusHeader();
             aldus.left = header.bounds.x;
@@ -84,7 +84,9 @@
 
         byte[] checksum = getChecksum(data);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(checksum);
+        for (int i=0; i<uidInstanceCount; i++) {
+            out.write(checksum);
+        }
         header.write(out);
         out.write(compressed);
 
@@ -99,12 +101,27 @@
     }
 
     /**
-     * WMF signature is <code>0x2160</code>
+     * WMF signature is either {@code 0x2160} or {@code 0x2170}
      */
     public int getSignature(){
-        return 0x2160;
+        return (uidInstanceCount == 1 ? 0x2160 : 0x2170);
     }
 
+    /**
+     * Sets the WMF signature - either {@code 0x2160} or {@code 0x2170}
+     */
+    public void setSignature(int signature) {
+        switch (signature) {
+            case 0x2160:
+                uidInstanceCount = 1;
+                break;
+            case 0x2170:
+                uidInstanceCount = 2;
+                break;
+            default:
+                throw new IllegalArgumentException(signature+" is not a valid instance/signature value for WMF");
+        }
+    }
 
     /**
      * Aldus Placeable Metafile header - 22 byte structure before WMF data.
diff --git a/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java b/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
index 0b57552..dad74ff 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
@@ -18,7 +18,6 @@
 package org.apache.poi.hslf.dev;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -28,7 +27,7 @@
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -50,9 +49,7 @@
     protected boolean hexHeader = true;
 
     public PPTXMLDump(File ppt) throws IOException {
-        FileInputStream fis = new FileInputStream(ppt);
-        POIFSFileSystem fs = new POIFSFileSystem(fis);
-        fis.close();
+        NPOIFSFileSystem fs = new NPOIFSFileSystem(ppt);
 
         //read the document entry from OLE file system
         DocumentEntry entry = (DocumentEntry)fs.getRoot().getEntry(PPDOC_ENTRY);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowDumper.java b/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowDumper.java
index 3954f6b..e098d40 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowDumper.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowDumper.java
@@ -17,11 +17,17 @@
 
 package org.apache.poi.hslf.dev;
 
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ddf.DefaultEscherRecordFactory;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherTextboxRecord;
+import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.ddf.*;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.hslf.record.HSLFEscherRecordFactory;
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.util.LittleEndian;
@@ -37,12 +43,9 @@
  * To peek inside PPDrawings, which hold Escher drawings, we use the
  *  DDF package from POI (but we can fake it by using the Escher listings
  *  from hslf.record.RecordTypes also)
- *
- * @author Nick Burch
  */
 public final class SlideShowDumper {
-  private InputStream istream;
-  private POIFSFileSystem filesystem;
+  private NPOIFSFileSystem filesystem;
 
   private byte[] _docstream;
 
@@ -91,7 +94,7 @@
    */
   public SlideShowDumper(String fileName) throws IOException
   {
-  	this(new FileInputStream(fileName));
+  	this(new NPOIFSFileSystem(new File(fileName)));
   }
 
   /**
@@ -104,8 +107,7 @@
   public SlideShowDumper(InputStream inputStream) throws IOException
   {
 	//do Ole stuff
-	this(new POIFSFileSystem(inputStream));
-	istream = inputStream;
+	this(new NPOIFSFileSystem(inputStream));
   }
 
   /**
@@ -115,7 +117,7 @@
    * @param filesystem the POIFS FileSystem to read from
    * @throws IOException if there is a problem while parsing the document.
    */
-  public SlideShowDumper(POIFSFileSystem filesystem) throws IOException
+  public SlideShowDumper(NPOIFSFileSystem filesystem) throws IOException
   {
 	this.filesystem = filesystem;
 
@@ -152,10 +154,7 @@
    */
   public void close() throws IOException
   {
-	if(istream != null) {
-		istream.close();
-	}
-	filesystem = null;
+	filesystem.close();
   }
 
 
diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
index 190ad0a..e3beebf 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
@@ -77,7 +77,7 @@
 	 * @param fileName The name of the file to extract from
 	 */
 	public PowerPointExtractor(String fileName) throws IOException {
-		this(new FileInputStream(fileName));
+		this(new NPOIFSFileSystem(new File(fileName)));
 	}
 
 	/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java
index 260eebd..8396ae1 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/QuickButCruddyTextExtractor.java
@@ -18,6 +18,9 @@
 package org.apache.poi.hslf.extractor;
 
 import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -25,7 +28,7 @@
 import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
 import org.apache.poi.hslf.usermodel.HSLFTextShape;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -45,11 +48,9 @@
  * Almost everyone will want to use @see PowerPointExtractor instead. There
  *  are only a very small number of cases (eg some performance sensitive
  *  lucene indexers) that would ever want to use this!
- *
- * @author Nick Burch
  */
 public final class QuickButCruddyTextExtractor {
-	private POIFSFileSystem fs;
+	private NPOIFSFileSystem fs;
 	private InputStream is;
 	private byte[] pptContents;
 
@@ -77,7 +78,7 @@
 	 * @param fileName
 	 */
 	public QuickButCruddyTextExtractor(String fileName) throws IOException {
-		this(new FileInputStream(fileName));
+		this(new NPOIFSFileSystem(new File(fileName)));
 	}
 
 	/**
@@ -85,7 +86,7 @@
 	 * @param iStream
 	 */
 	public QuickButCruddyTextExtractor(InputStream iStream) throws IOException {
-		this(new POIFSFileSystem(iStream));
+		this(new NPOIFSFileSystem(iStream));
 		is = iStream;
 	}
 
@@ -93,7 +94,7 @@
 	 * Creates an extractor from a POIFS Filesystem
 	 * @param poifs
 	 */
-	public QuickButCruddyTextExtractor(POIFSFileSystem poifs) throws IOException {
+	public QuickButCruddyTextExtractor(NPOIFSFileSystem poifs) throws IOException {
 		fs = poifs;
 
 		// Find the PowerPoint bit, and get out the bytes
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
index 0ed4357..e34103a 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
@@ -30,21 +30,18 @@
 import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.StringUtil;
 
-
 /**
- * This is a special kind of Atom, becauase it doesn't live inside the
- *  PowerPoint document. Instead, it lives in a seperate stream in the
- *  document. As such, it has to be treaded specially
- *
- * @author Nick Burch
+ * This is a special kind of Atom, because it doesn't live inside the
+ *  PowerPoint document. Instead, it lives in a separate stream in the
+ *  document. As such, it has to be treated specially
  */
-
 public class CurrentUserAtom
 {
 	private static POILogger logger = POILogFactory.getLogger(CurrentUserAtom.class);
@@ -117,6 +114,7 @@
 
 	/** 
 	 * Find the Current User in the filesystem, and create from that
+	 * @deprecated Use {@link #CurrentUserAtom(DirectoryNode)} instead
 	 */
 	public CurrentUserAtom(POIFSFileSystem fs) throws IOException {
 		this(fs.getRoot());
@@ -278,7 +276,7 @@
 	/**
 	 * Writes ourselves back out to a filesystem
 	 */
-	public void writeToFS(POIFSFileSystem fs) throws IOException {
+	public void writeToFS(NPOIFSFileSystem fs) throws IOException {
 		// Grab contents
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 		writeOut(baos);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
index 230a640..aa7e8a3 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
@@ -51,6 +51,11 @@
     protected int offset;
 
     /**
+     * The instance type/signatures defines if one or two UID instances will be included
+     */
+    protected int uidInstanceCount = 1;
+    
+    /**
      * Returns type of this picture.
      * Must be one of the static constants defined in the <code>Picture<code> class.
      *
@@ -82,6 +87,15 @@
      */
     protected abstract int getSignature();
 
+    public abstract void setSignature(int signature);
+
+    /**
+     * The instance type/signatures defines if one or two UID instances will be included
+     */
+    protected int getUIDInstanceCount() {
+        return uidInstanceCount;
+    }
+
     /**
      * Returns the raw binary data of this Picture excluding the first 8 bytes
      * which hold image signature and size of the image data.
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
index 9288052..2ecb7ef 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
@@ -184,11 +184,12 @@
             h = clientRec.getRow1()-clientRec.getCol1();
         }
 
+        // TODO: find out where this -1 value comes from at #57820 (link to ms docs?)
         Rectangle2D anchor = new Rectangle2D.Float(
-            (float)Units.masterToPoints(x),
-            (float)Units.masterToPoints(y),
-            (float)Units.masterToPoints(w),
-            (float)Units.masterToPoints(h)
+            (float)(x == -1 ? -1 : Units.masterToPoints(x)),
+            (float)(y == -1 ? -1 : Units.masterToPoints(y)),
+            (float)(w == -1 ? -1 : Units.masterToPoints(w)),
+            (float)(h == -1 ? -1 : Units.masterToPoints(h))
         );
         
         return anchor;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
index ec5f735..34638f6 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
@@ -83,14 +83,6 @@
     // Embedded objects stored in storage records in the document stream, lazily populated.
     private HSLFObjectData[] _objects;
     
-    /**
-	 * Returns the underlying POIFSFileSystem for the document
-	 *  that is open.
-	 */
-	protected POIFSFileSystem getPOIFSFileSystem() {
-		return directory.getFileSystem();
-	}
-
    /**
     * Returns the directory in the underlying POIFSFileSystem for the 
     *  document that is open.
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
index 29fdee2..d9f5b11 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
@@ -178,7 +178,7 @@
             }
         });
         
-        int y0 = -1;
+        int y0 = (shapeList.isEmpty()) ? -1 : shapeList.get(0).getAnchor().y - 1;
         int maxrowlen = 0;
         List<List<HSLFShape>> lst = new ArrayList<List<HSLFShape>>();
         List<HSLFShape> row = null;
diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java
index c8867a6..dd9ab9a 100644
--- a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java
+++ b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java
@@ -69,15 +69,28 @@
       for(String part : parts) {
          if(part.startsWith("l=")) {
             // Format of this bit appears to be l=<id>-<time>-<number>
-            if(part.indexOf('-') != -1 && 
-                  part.indexOf('-') != part.lastIndexOf('-')) {
-               String dateS = part.substring(part.indexOf('-')+1, part.lastIndexOf('-'));
-               
+            // ID may contain hyphens.
+
+            String dateS = null;
+            final int numberPartBegin = part.lastIndexOf('-');
+            if (numberPartBegin != -1) {
+                final int datePartBegin = part.lastIndexOf('-', numberPartBegin-1);
+                if (datePartBegin != -1 && 
+                        // cannot extract date if only one hyphen is in the string...
+                        numberPartBegin > datePartBegin) {
+                    dateS = part.substring(datePartBegin + 1, numberPartBegin);
+                }
+            }
+            if (dateS != null) {
                // Should be yymmddhhmmssZ
                Matcher m = datePatern.matcher(dateS);
                if(m.matches()) {
                   date = Calendar.getInstance();
-                  date.set(Calendar.YEAR,  Integer.parseInt(m.group(1)) + 2000);
+
+                  // work around issues with dates like 1989, which appear as "89" here
+                  int year = Integer.parseInt(m.group(1));
+                  date.set(Calendar.YEAR,  year + (year > 80 ? 1900 : 2000));
+
                   date.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1); // Java is 0 based
                   date.set(Calendar.DATE,  Integer.parseInt(m.group(3)));
                   date.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
index 7012887..8aef34b 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
@@ -67,10 +67,10 @@
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.poifs.filesystem.EntryUtils;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.Internal;
 
-
 /**
  *
  * This class acts as the bucket that we throw all of the Word data structures
@@ -924,7 +924,7 @@
     }
 
         // create new document preserving order of entries
-        POIFSFileSystem pfs = new POIFSFileSystem();
+        NPOIFSFileSystem pfs = new NPOIFSFileSystem();
         boolean docWritten = false;
         boolean dataWritten = false;
         boolean objectPoolWritten = false;
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
index d8e4109..04fe38c 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
@@ -85,7 +85,7 @@
   }
 
   /**
-   * Takens an InputStream, verifies that it's not RTF, builds a
+   * Takens an InputStream, verifies that it's not RTF or PDF, builds a
    *  POIFSFileSystem from it, and returns that.
    */
   public static POIFSFileSystem verifyAndBuildPOIFS(InputStream istream) throws IOException {
@@ -98,9 +98,11 @@
 	if(first6[0] == '{' && first6[1] == '\\' && first6[2] == 'r'
 		&& first6[3] == 't' && first6[4] == 'f') {
 		throw new IllegalArgumentException("The document is really a RTF file");
+	} else if(first6[0] == '%' && first6[1] == 'P' && first6[2] == 'D' && first6[3] == 'F' ) {
+		throw new IllegalArgumentException("The document is really a PDF file");
 	}
 
-	// OK, so it's not RTF
+	// OK, so it's neither RTF nor PDF
 	// Open a POIFSFileSystem on the (pushed back) stream
 	pis.unread(first6);
 	return new POIFSFileSystem(pis);
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
index 95da850..29875d6 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
@@ -850,7 +850,7 @@
             String[] values = cr.getDropDownListValues();
             Integer defIndex = cr.getDropDownListDefaultItemIndex();
 
-            if ( values != null )
+            if ( values != null && values.length > 0 )
             {
                 processDropDownList( currentBlock, cr, values,
                         defIndex == null ? -1 : defIndex.intValue() );
@@ -1034,7 +1034,6 @@
         }
     }
 
-    @SuppressWarnings( "unused" )
     protected boolean processOle2( HWPFDocument wordDocument, Element block,
             Entry entry ) throws Exception
     {
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/extractor/Word6Extractor.java b/src/scratchpad/src/org/apache/poi/hwpf/extractor/Word6Extractor.java
index 1d5ec63..5807740 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/extractor/Word6Extractor.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/extractor/Word6Extractor.java
@@ -38,7 +38,6 @@
  * @author Nick Burch
  */
 public final class Word6Extractor extends POIOLE2TextExtractor {
-	private POIFSFileSystem fs;
 	private HWPFOldDocument doc;
 
 	/**
@@ -64,7 +63,6 @@
      * @deprecated Use {@link #Word6Extractor(DirectoryNode)} instead
      */
     @Deprecated
-    @SuppressWarnings( "unused" )
     public Word6Extractor( DirectoryNode dir, POIFSFileSystem fs )
             throws IOException
     {
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/extractor/WordExtractor.java b/src/scratchpad/src/org/apache/poi/hwpf/extractor/WordExtractor.java
index dc06fb9..ee0a615 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/extractor/WordExtractor.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/extractor/WordExtractor.java
@@ -68,7 +68,6 @@
      * @deprecated Use {@link #WordExtractor(DirectoryNode)} instead
      */
     @Deprecated
-    @SuppressWarnings( "unused" )
     public WordExtractor( DirectoryNode dir, POIFSFileSystem fs )
             throws IOException
     {
@@ -109,7 +108,11 @@
         // Process the first argument as a file
         FileInputStream fin = new FileInputStream( args[0] );
         WordExtractor extractor = new WordExtractor( fin );
-        System.out.println( extractor.getText() );
+        try {
+        	System.out.println( extractor.getText() );
+        } finally {
+        	extractor.close();
+        }
     }
 
     /**
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java
index 33100e5..18747c4 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java
@@ -53,7 +53,7 @@
             .getLogger( CHPBinTable.class );
 
   /** List of character properties.*/
-  protected ArrayList<CHPX> _textRuns = new ArrayList<CHPX>();
+  protected List<CHPX> _textRuns = new ArrayList<CHPX>();
 
   public CHPBinTable()
   {
@@ -498,7 +498,7 @@
         int endingFc = translator.getByteIndex( _textRuns.get(
                 _textRuns.size() - 1 ).getEnd() );
 
-    ArrayList<CHPX> overflow = _textRuns;
+    List<CHPX> overflow = _textRuns;
     do
     {
       CHPX startingProp = overflow.get(0);
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java
index 6b14100..ee50fb5 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java
@@ -62,7 +62,6 @@
      *             {@link #CHPFormattedDiskPage(byte[], int, CharIndexTranslator)}
      *             instead
      */
-    @SuppressWarnings( "unused" )
     public CHPFormattedDiskPage( byte[] documentStream, int offset, int fcMin,
             TextPieceTable tpt )
     {
@@ -145,7 +144,6 @@
      * @deprecated Use {@link #toByteArray(CharIndexTranslator)} instead
      */
     @Deprecated
-    @SuppressWarnings( "unused" )
     protected byte[] toByteArray(CharIndexTranslator translator, int fcMin)
     {
         return toByteArray( translator );
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java
index f8e331f..5c8b9b9 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java
@@ -174,6 +174,41 @@
         return _lvlf.getIxchFollow();
     }
 
+    /**
+     * An unsigned integer that specifies the first (most-significant) zero-based level after which the number sequence of this level does not restart. The number sequence of this level does restart after any level that is more significant than the specified level. This MUST be less than or equal to the zero-based level of the list to which this LVLF corresponds.
+     * <p>see [MS-DOC], v20140721, 2.9.150</p>
+     * 
+     * @return the first ({@code 0} is the most significant) level after which
+     * the numbering does not restart or {@code -1} if no restart is applicable
+     */
+    public short getRestart() {    	
+    	return _lvlf.isFNoRestart() ? _lvlf.getIlvlRestartLim() : -1;
+    }
+    
+    /**
+     * Determines if the number formatting shall be overridden by
+     * {@code msonfcArabic}; unless it originally was {@code msonfcArabicLZ}
+     * in which case it is preserved.
+     * <p>see [MS-DOC], v20140721, 2.9.150 and [MS-OSHARED], v20140721, 2.2.1.3</p>
+     * 
+     * @return {@code true} if the level numbering of this and all more
+     * significant levels must be overridden; {@code false} otherwise
+     */
+    public boolean isLegalNumbering() {
+    	return _lvlf.isFLegal();
+    }
+    
+    /**
+     * Array which specifies the character offsets of the level numbers in a
+     * level numbering string.
+     * <p>see [MS-DOC], v20140721, 2.9.150</p>
+     * 
+     * @return {@code 0}-terminated array, unless it is full 
+     */
+    public byte[] getLevelNumberingPlaceholderOffsets() {    	
+    	return _lvlf.getRgbxchNums();
+    }
+
     int read( final byte[] data, final int startOffset )
     {
         int offset = startOffset;
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java
index 5414c27..956b1b9 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java
@@ -38,11 +38,11 @@
   private final static POILogger _logger = POILogFactory.getLogger(SectionTable.class);
   private static final int SED_SIZE = 12;
 
-  protected ArrayList<SEPX> _sections = new ArrayList<SEPX>();
+  protected List<SEPX> _sections = new ArrayList<SEPX>();
   protected List<TextPiece> _text;
 
   /** So we can know if things are unicode or not */
-  private TextPieceTable tpt;
+  //private TextPieceTable tpt;
 
   public SectionTable()
   {
@@ -54,7 +54,7 @@
                       TextPieceTable tpt, int mainLength)
   {
     PlexOfCps sedPlex = new PlexOfCps(tableStream, offset, size, SED_SIZE);
-    this.tpt = tpt;
+    //this.tpt = tpt;
     this._text = tpt.getTextPieces();
 
     int length = sedPlex.length();
@@ -160,7 +160,7 @@
     // return FC;
     // }
 
-  public ArrayList<SEPX> getSections()
+  public List<SEPX> getSections()
   {
     return _sections;
   }
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java
index fd6d631..3c5e25f 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java
@@ -382,7 +382,7 @@
             cp.setDttmPropRMark( (DateAndTime) getDttmPropRMark().clone() );
             cp.setDttmDispFldRMark( (DateAndTime) getDttmDispFldRMark().clone() );
             cp.setXstDispFldRMark( getXstDispFldRMark().clone() );
-            cp.setShd( (ShadingDescriptor) getShd().clone() );
+            cp.setShd( getShd().clone() );
             cp.setBrc( (BorderCode) getBrc().clone() );
 
             return cp;
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java
index d02f8ae..4181c19 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java
@@ -570,7 +570,7 @@
     cp._props.setDttmDispFldRMark((DateAndTime)_props.getDttmDispFldRMark().
                                   clone());
     cp._props.setXstDispFldRMark(_props.getXstDispFldRMark().clone());
-    cp._props.setShd((ShadingDescriptor)_props.getShd().clone());
+    cp._props.setShd(_props.getShd().clone());
 
     return cp;
   }
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HWPFList.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HWPFList.java
index 41bcb96..6f69f71 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HWPFList.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HWPFList.java
@@ -17,10 +17,6 @@
 
 package org.apache.poi.hwpf.usermodel;
 
-import org.apache.poi.util.POILogFactory;
-
-import org.apache.poi.util.POILogger;
-
 import org.apache.poi.hwpf.model.ListTables;
 
 import org.apache.poi.util.Internal;
@@ -52,7 +48,7 @@
  */
 public final class HWPFList
 {
-    private static POILogger log = POILogFactory.getLogger( HWPFList.class );
+    //private static POILogger log = POILogFactory.getLogger( HWPFList.class );
 
     private boolean _ignoreLogicalLeftIdentation = false;
     private LFO _lfo;
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java
index 7583b59..1dbeae4 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java
@@ -43,7 +43,7 @@
         pp.setBrcBar( (BorderCode) getBrcBar().clone() );
         pp.setDcs( getDcs().clone() );
         pp.setLspd( (LineSpacingDescriptor) getLspd().clone() );
-        pp.setShd( (ShadingDescriptor) getShd().clone() );
+        pp.setShd( getShd().clone() );
         pp.setPhe( getPhe().clone() );
         return pp;
     }
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableCellDescriptor.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableCellDescriptor.java
index 812e3b6..4d01ec8 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableCellDescriptor.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableCellDescriptor.java
@@ -53,7 +53,7 @@
     throws CloneNotSupportedException
   {
     TableCellDescriptor tc = (TableCellDescriptor)super.clone();
-    tc.setShd( (ShadingDescriptor) getShd().clone() );
+    tc.setShd( getShd().clone() );
     tc.setBrcTop((BorderCode)getBrcTop().clone());
     tc.setBrcLeft((BorderCode)getBrcLeft().clone());
     tc.setBrcBottom((BorderCode)getBrcBottom().clone());
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableProperties.java
index 31c3d97..001b3cf 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableProperties.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableProperties.java
@@ -71,7 +71,7 @@
         tap.setRgshd( new ShadingDescriptor[getRgshd().length] );
         for ( int x = 0; x < getRgshd().length; x++ )
         {
-            tap.getRgshd()[x] = (ShadingDescriptor) getRgshd()[x].clone();
+            tap.getRgshd()[x] = getRgshd()[x].clone();
         }
 
         tap.setBrcBottom( (BorderCode) getBrcBottom().clone() );
@@ -81,7 +81,7 @@
         tap.setBrcTop( (BorderCode) getBrcTop().clone() );
         tap.setBrcVertical( (BorderCode) getBrcVertical().clone() );
 
-        tap.setShdTable( (ShadingDescriptor) getShdTable().clone() );
+        tap.setShdTable( getShdTable().clone() );
 
         tap.setRgbrcInsideDefault_0( (BorderCode) getRgbrcInsideDefault_0()
                 .clone() );
diff --git a/src/scratchpad/testcases/org/apache/poi/TestPOIDocumentScratchpad.java b/src/scratchpad/testcases/org/apache/poi/TestPOIDocumentScratchpad.java
index 652314c..30296cf 100644
--- a/src/scratchpad/testcases/org/apache/poi/TestPOIDocumentScratchpad.java
+++ b/src/scratchpad/testcases/org/apache/poi/TestPOIDocumentScratchpad.java
@@ -75,7 +75,7 @@
 
 	public void testWriteProperties() throws Exception {
 		// Just check we can write them back out into a filesystem
-		POIFSFileSystem outFS = new POIFSFileSystem();
+		NPOIFSFileSystem outFS = new NPOIFSFileSystem();
 		doc.writeProperties(outFS);
 
 		// Should now hold them
@@ -87,7 +87,7 @@
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
     	// Write them out
-    	POIFSFileSystem outFS = new POIFSFileSystem();
+    	NPOIFSFileSystem outFS = new NPOIFSFileSystem();
     	doc.writeProperties(outFS);
     	outFS.writeFilesystem(baos);
 
diff --git a/src/scratchpad/testcases/org/apache/poi/hdf/extractor/TestWordDocument.java b/src/scratchpad/testcases/org/apache/poi/hdf/extractor/TestWordDocument.java
index 1cf29f4..f094167 100644
--- a/src/scratchpad/testcases/org/apache/poi/hdf/extractor/TestWordDocument.java
+++ b/src/scratchpad/testcases/org/apache/poi/hdf/extractor/TestWordDocument.java
@@ -17,6 +17,15 @@
 
 package org.apache.poi.hdf.extractor;
 
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.poi.hwpf.HWPFDocument;
+import org.apache.poi.hwpf.HWPFTestDataSamples;
+import org.apache.poi.hwpf.extractor.WordExtractor;
 import org.junit.Test;
 
 
@@ -31,4 +40,31 @@
         //WordDocument.main(new String[] {"test-data/document/Word6.doc", "/tmp/test.doc"});
         WordDocument.main(new String[] {"test-data/document/53446.doc", "/tmp/test.doc"});
     }
+
+    @SuppressWarnings("deprecation")
+	@Test
+    public void test47304() throws IOException {
+    	HWPFDocument doc = HWPFTestDataSamples.openSampleFile("47304.doc");
+    	assertNotNull(doc);
+    	
+    	WordExtractor extractor = new WordExtractor(doc);
+        String text = extractor.getText();
+        //System.out.println(text);
+        assertTrue("Had: " + text, text.contains("Just  a \u201Ctest\u201D"));
+        extractor.close();
+        
+		WordDocument wordDoc = new WordDocument("test-data/document/47304.doc");
+        
+        StringWriter docTextWriter = new StringWriter();
+        PrintWriter out = new PrintWriter(docTextWriter);
+        try {
+        	wordDoc.writeAllText(out);
+        } finally {
+        	out.close();
+        }
+        docTextWriter.close();
+
+        //System.out.println(docTextWriter.toString());
+        assertTrue("Had: " + docTextWriter.toString(), docTextWriter.toString().contains("Just  a \u201Ctest\u201D"));
+    }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
index 3337d58..fb49dbb 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
@@ -17,14 +17,27 @@
 
 package org.apache.poi.hslf.model;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.List;
 
+import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFSlide;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFTable;
+import org.apache.poi.hslf.usermodel.HSLFTableCell;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.TableShape;
 import org.junit.Test;
 
 /**
@@ -33,6 +46,7 @@
  * @author Yegor Kozlov
  */
 public final class TestTable {
+    private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
 
     /**
      * Test that ShapeFactory works properly and returns <code>Table</code>
@@ -105,4 +119,31 @@
 
         }
     }
+    
+    /**
+     * Bug 57820: initTable throws NullPointerException
+     * when the table is positioned with its top at -1
+     */
+    @Test
+    public void test57820() throws Exception {
+        SlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("bug57820-initTableNullRefrenceException.ppt"));
+
+        List<? extends Slide<?,?,?>> slides = ppt.getSlides();
+        assertEquals(1, slides.size());
+
+        List<? extends Shape> shapes = slides.get(0).getShapes(); //throws NullPointerException
+
+        TableShape tbl = null;
+        for(Shape s : shapes) {
+            if(s instanceof TableShape) {
+                tbl = (TableShape)s;
+                break;
+            }
+        }
+
+        assertNotNull(tbl);
+
+        // handling changed in common sl, so it evaluates to 0 now
+        assertEquals(0, tbl.getAnchor().getY(), 0);
+    }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
index 14200d5..5ede8b0 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
@@ -34,6 +34,7 @@
 import org.apache.poi.sl.usermodel.Slide;
 import org.apache.poi.sl.usermodel.SlideShow;
 import org.apache.poi.util.JvmBugs;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -138,7 +139,7 @@
     }
 
     @Test
-    // @Ignore("Just for visual validation - antialiasing is different on various systems")
+    @Ignore("Just for visual validation - antialiasing is different on various systems")
     public void bug54541() throws Exception {
         String files[] = {
 //            "sample_pptx_grouping_issues.pptx",
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
index 8ad3ba6..ce49cd5 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
@@ -413,10 +413,6 @@
         fs.close();		
 		byte[] raw_ss = baos.toByteArray();
 		
-		FileOutputStream fos = new FileOutputStream("PowerPoint Document.new.stream");
-		fos.write(raw_ss);
-		fos.close();
-
 		// different paragraph mask, because of sanitizing
 		raw_ss[169030] = 0x0a;
 		
diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java b/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java
index 710d991..7664bdd 100644
--- a/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java
+++ b/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java
@@ -27,19 +27,19 @@
 public final class AllHSMFTests {
    public static Test suite() {
       TestSuite suite = new TestSuite(AllHSMFTests.class.getName());
+
       suite.addTestSuite(TestBasics.class);
       suite.addTestSuite(TestBlankFileRead.class);
       suite.addTestSuite(TestSimpleFileRead.class);
       suite.addTestSuite(TestOutlook30FileRead.class);
       suite.addTestSuite(TestFileWithAttachmentsRead.class);
-
       suite.addTestSuite(TestChunkData.class);
       suite.addTestSuite(TestTypes.class);
       suite.addTestSuite(TestSorters.class);
-
       suite.addTestSuite(TestOutlookTextExtractor.class);
-      
       suite.addTestSuite(TestPOIFSChunkParser.class);
+      suite.addTestSuite(TestMessageSubmissionChunkY2KRead.class);
+      suite.addTestSuite(TestMessageSubmissionChunk.class);
 
       return suite;
    }
diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunk.java b/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunk.java
new file mode 100644
index 0000000..0cbad21
--- /dev/null
+++ b/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunk.java
@@ -0,0 +1,58 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+

+package org.apache.poi.hsmf;

+

+import java.io.IOException;

+

+import org.apache.poi.hsmf.MAPIMessage;

+import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;

+import org.apache.poi.POIDataSamples;

+

+import java.util.Calendar;

+

+import junit.framework.TestCase;

+

+public final class TestMessageSubmissionChunk extends TestCase {

+    

+    private MAPIMessage mapiMessageExtraHyphenSubmissionChunk;

+    private MAPIMessage mapiMessageNormalSubmissionChunk;

+

+    /**

+     * Initialise this test, load up the test messages.

+     * @throws Exception

+     */

+    public TestMessageSubmissionChunk() throws IOException {

+        POIDataSamples samples = POIDataSamples.getHSMFInstance();

+        this.mapiMessageExtraHyphenSubmissionChunk = new MAPIMessage(samples.openResourceAsStream("message_extra_hyphen_submission_chunk.msg"));

+        this.mapiMessageNormalSubmissionChunk = new MAPIMessage(samples.openResourceAsStream("message_normal_submission_chunk.msg"));

+    }

+

+    public void testReadMessageDateExtraHyphenSubmissionChunk() throws ChunkNotFoundException {

+        final Calendar date = mapiMessageExtraHyphenSubmissionChunk.getMessageDate();

+        TestCase.assertNotNull(date);

+        final int year = date.get(Calendar.YEAR);

+        TestCase.assertEquals(2007, year);

+    }

+

+    public void testReadMessageDateNormalSubmissionChunk() throws ChunkNotFoundException {

+        final Calendar date = mapiMessageNormalSubmissionChunk.getMessageDate();

+        TestCase.assertNotNull(date);

+        final int year = date.get(Calendar.YEAR);

+        TestCase.assertEquals(2007, year);

+    }

+}

diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunkY2KRead.java b/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunkY2KRead.java
new file mode 100644
index 0000000..c10ba0b
--- /dev/null
+++ b/src/scratchpad/testcases/org/apache/poi/hsmf/TestMessageSubmissionChunkY2KRead.java
@@ -0,0 +1,67 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+

+package org.apache.poi.hsmf;

+

+import java.io.IOException;

+

+import org.apache.poi.hsmf.MAPIMessage;

+import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;

+import org.apache.poi.POIDataSamples;

+

+import java.util.Calendar;

+

+import junit.framework.TestCase;

+

+public final class TestMessageSubmissionChunkY2KRead extends TestCase {

+    

+    private MAPIMessage mapiMessage1979;

+    private MAPIMessage mapiMessage1980;

+    private MAPIMessage mapiMessage1981;

+

+    /**

+     * Initialise this test, load up the three test messages.

+     * @throws Exception

+     */

+    public TestMessageSubmissionChunkY2KRead() throws IOException {

+        POIDataSamples samples = POIDataSamples.getHSMFInstance();

+        this.mapiMessage1979 = new MAPIMessage(samples.openResourceAsStream("message_1979.msg"));

+        this.mapiMessage1980 = new MAPIMessage(samples.openResourceAsStream("message_1980.msg"));

+        this.mapiMessage1981 = new MAPIMessage(samples.openResourceAsStream("message_1981.msg"));

+    }

+

+    // 1979 is one year before our pivot year (so this is an expected "failure")

+    public void testReadMessageDate1979() throws ChunkNotFoundException {

+        final Calendar date = mapiMessage1979.getMessageDate();

+        final int year = date.get(Calendar.YEAR);

+        TestCase.assertEquals(2079, year);

+    }

+

+    // 1980 is our pivot year (so this is an expected "failure")

+    public void testReadMessageDate1980() throws ChunkNotFoundException {

+        final Calendar date = mapiMessage1980.getMessageDate();

+        final int year = date.get(Calendar.YEAR);

+        TestCase.assertEquals(2080, year);

+    }

+

+    // 1981 is one year after our pivot year (so this starts working)

+    public void testReadMessageDate1981() throws ChunkNotFoundException {

+        final Calendar date = mapiMessage1981.getMessageDate();

+        final int year = date.get(Calendar.YEAR);

+        TestCase.assertEquals(1981, year);

+    }

+}

diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java b/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java
index 3d276ce..adbb966 100644
--- a/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java
+++ b/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java
@@ -60,6 +60,8 @@
       String dateText = f.format(cal.getTime());
       assertContains(text, "Date: " + dateText + "\n");
       assertContains(text, "The quick brown fox jumps over the lazy dog");
+
+      ext.close();
    }
    
    public void testSimple() throws Exception {
@@ -77,21 +79,28 @@
       assertContains(text, "Subject: test message\n");
       assertContains(text, "Date: Fri, 6 Jul 2007 05:27:17 +0000\n");
       assertContains(text, "This is a test message.");
+
+      ext.close();
    }
 
    public void testConstructors() throws Exception {
-      String inp = (new OutlookTextExtactor(new FileInputStream(
-            samples.getFile("simple_test_msg.msg")
-      )).getText());
-      String poifs = (new OutlookTextExtactor(new POIFSFileSystem(new FileInputStream(
-            samples.getFile("simple_test_msg.msg")
-      ))).getText());
-      String mapi = (new OutlookTextExtactor(new MAPIMessage(new FileInputStream(
-            samples.getFile("simple_test_msg.msg")
-      ))).getText());
-      
-      assertEquals(inp, poifs);
-      assertEquals(inp, mapi);
+        OutlookTextExtactor ext = new OutlookTextExtactor(new FileInputStream(
+                samples.getFile("simple_test_msg.msg")));
+        String inp = ext.getText();
+        ext.close();
+
+        ext = new OutlookTextExtactor(new POIFSFileSystem(new FileInputStream(
+                samples.getFile("simple_test_msg.msg"))));
+        String poifs = ext.getText();
+        ext.close();
+
+        ext = new OutlookTextExtactor(new MAPIMessage(new FileInputStream(
+                samples.getFile("simple_test_msg.msg"))));
+        String mapi = ext.getText();
+        ext.close();
+
+        assertEquals(inp, poifs);
+        assertEquals(inp, mapi);
    }
    
    /**
@@ -128,6 +137,8 @@
          assertContains(text, "Subject: This is a test message please ignore\n");
          assertContains(text, "Date:");
          assertContains(text, "The quick brown fox jumps over the lazy dog");
+
+         ext.close();
       }
    }
    
@@ -164,6 +175,8 @@
          assertContains(text, "Subject: This is a test message please ignore\n");
          assertContains(text, "Date: Mon, 11 Jan 2010 16:2"); // Exact times differ slightly
          assertContains(text, "The quick brown fox jumps over the lazy dog");
+
+         ext.close();
       }
    }
    
@@ -192,6 +205,8 @@
       
       // Embeded bits are checked in
       //  TestExtractorFactory
+
+      ext.close();
    }
    
    public void testEncodings() throws Exception {
@@ -209,5 +224,7 @@
       // And check some chinese bits
       assertContains(text, "(\u5f35\u6bd3\u502b)");
       assertContains(text, "( MSG \u683c\u5f0f\u6e2c\u8a66 )");
+
+      ext.close();
    }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/extractor/TestWordExtractor.java b/src/scratchpad/testcases/org/apache/poi/hwpf/extractor/TestWordExtractor.java
index 82d6f34..1a69630 100644
--- a/src/scratchpad/testcases/org/apache/poi/hwpf/extractor/TestWordExtractor.java
+++ b/src/scratchpad/testcases/org/apache/poi/hwpf/extractor/TestWordExtractor.java
@@ -20,6 +20,7 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.POITextExtractor;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.HWPFTestDataSamples;
 import org.apache.poi.hwpf.OldWordFileFormatException;
@@ -377,10 +378,35 @@
         for (Entry entry : fs.getRoot()) {
             if ("WordDocument".equals(entry.getName())) {
                 WordExtractor ex = new WordExtractor(fs);
-                text = ex.getText();
+                try {
+                    text = ex.getText();
+                } finally {
+                    ex.close();
+                }
             }
         }
 
         assertNotNull(text);
     }
+
+
+    public void testExtractorFromWord6Extractor() throws Exception {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getHPSFInstance().openResourceAsStream("TestMickey.doc"));
+        Word6Extractor wExt = new Word6Extractor(fs);
+        try {
+            POITextExtractor ext = wExt.getMetadataTextExtractor();
+            try {
+                // Now overall
+                String text = ext.getText();
+                assertTrue(text.indexOf("TEMPLATE = Normal") > -1);
+                assertTrue(text.indexOf("SUBJECT = sample subject") > -1);
+                assertTrue(text.indexOf("MANAGER = sample manager") > -1);
+                assertTrue(text.indexOf("COMPANY = sample company") > -1);
+            } finally {
+                ext.close();
+            }
+        } finally {
+            wExt.close();
+        }
+    }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestCHPBinTable.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestCHPBinTable.java
index a36a729..d98390d 100644
--- a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestCHPBinTable.java
+++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestCHPBinTable.java
@@ -18,7 +18,7 @@
 package org.apache.poi.hwpf.model;
 
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
+import java.util.List;
 
 import junit.framework.TestCase;
 
@@ -59,16 +59,16 @@
 
     CHPBinTable newBinTable = new CHPBinTable(newMainStream, newTableStream, 0, newTableStream.length, fakeTPT);
 
-    ArrayList oldTextRuns = _cHPBinTable._textRuns;
-    ArrayList newTextRuns = newBinTable._textRuns;
+    List<CHPX> oldTextRuns = _cHPBinTable._textRuns;
+    List<CHPX> newTextRuns = newBinTable._textRuns;
 
     assertEquals(oldTextRuns.size(), newTextRuns.size());
 
     int size = oldTextRuns.size();
     for (int x = 0; x < size; x++)
     {
-      PropertyNode oldNode = (PropertyNode)oldTextRuns.get(x);
-      PropertyNode newNode = (PropertyNode)newTextRuns.get(x);
+      CHPX oldNode = oldTextRuns.get(x);
+      CHPX newNode = newTextRuns.get(x);
       assertTrue(oldNode.equals(newNode));
     }
 
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java
index 61e5376..6fb9216 100644
--- a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java
+++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java
@@ -20,7 +20,7 @@
 import junit.framework.*;
 
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.poi.hwpf.*;
 import org.apache.poi.hwpf.model.io.*;
@@ -58,8 +58,8 @@
     		newMainStream, newTableStream, 0,
     		newTableStream.length, 0, tpt, fib.getSubdocumentTextStreamLength( SubdocumentType.MAIN ));
 
-    ArrayList oldSections = sectionTable.getSections();
-    ArrayList newSections = newSectionTable.getSections();
+    List<SEPX> oldSections = sectionTable.getSections();
+    List<SEPX> newSections = newSectionTable.getSections();
 
     assertEquals(oldSections.size(), newSections.size());
 
@@ -79,8 +79,8 @@
     int size = oldSections.size();
     for (int x = 0; x < size; x++)
     {
-      PropertyNode oldNode = (PropertyNode)oldSections.get(x);
-      PropertyNode newNode = (PropertyNode)newSections.get(x);
+	  SEPX oldNode = oldSections.get(x);
+	  SEPX newNode = newSections.get(x);
       assertEquals(oldNode, newNode);
     }
   }
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestLists.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestLists.java
index eafb18f..d2c9ac9 100644
--- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestLists.java
+++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestLists.java
@@ -23,6 +23,7 @@
 
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.HWPFTestDataSamples;
+import org.apache.poi.hwpf.model.ListLevel;
 
 /**
  * Tests for our handling of lists
@@ -207,4 +208,47 @@
       assertEquals(1, r.getParagraph(22).getIlvl());
       assertEquals(0, r.getParagraph(23).getIlvl());
    }
+
+   public void testSpecificNumberedOrderedListFeatures() throws IOException {
+      HWPFDocument doc = HWPFTestDataSamples.openSampleFile("Lists.doc");
+
+      Range r = doc.getRange();
+      //these are in the numbered ordered list
+      //26 = OL 2
+      //27 = OL 2.1
+      //28 = OL 2.2
+      //29 = OL 2.2.1
+      for (int i = 26; i < 30; i++) {
+         Paragraph p = r.getParagraph(i);
+         assertTrue(p.isInList());
+         HWPFList list = p.getList();
+         ListLevel level = list.getLVL((char) p.getIlvl());
+         assertFalse(level.isLegalNumbering());
+         assertEquals(-1, level.getRestart());
+      }
+      Paragraph p = r.getParagraph(26);
+      HWPFList list = p.getList();
+      ListLevel level = list.getLVL((char) p.getIlvl());
+      byte[] lvl = level.getLevelNumberingPlaceholderOffsets();
+
+      assertEquals((byte)1, lvl[0]);
+      assertEquals((byte)0, lvl[1]);
+
+      p = r.getParagraph(27);
+      list = p.getList();
+      level = list.getLVL((char) p.getIlvl());
+      lvl = level.getLevelNumberingPlaceholderOffsets();
+      assertEquals((byte)1, lvl[0]);
+      assertEquals((byte)3, lvl[1]);
+
+      p = r.getParagraph(29);
+      list = p.getList();
+      level = list.getLVL((char) p.getIlvl());
+      lvl = level.getLevelNumberingPlaceholderOffsets();
+
+      assertEquals((byte)1, lvl[0]);
+      assertEquals((byte)3, lvl[1]);
+      assertEquals((byte)5, lvl[2]);
+   }
+
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRange.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRange.java
index ab4a196..a7eabe5 100644
--- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRange.java
+++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRange.java
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hwpf.usermodel;
 
-import java.util.ArrayList;
+import java.util.List;
 
 import junit.framework.TestCase;
 
@@ -62,7 +62,7 @@
         HWPFDocument hwpfDocument = new HWPFDocument( POIDataSamples
                 .getDocumentInstance().openResourceAsStream( "Bug46817.doc" ) );
 
-        final ArrayList<SEPX> sections = hwpfDocument.getSectionTable()
+        final List<SEPX> sections = hwpfDocument.getSectionTable()
                 .getSections();
         assertEquals( sections.size(), 1 );
 
diff --git a/src/testcases/org/apache/poi/POITestCase.java b/src/testcases/org/apache/poi/POITestCase.java
index 7a1a027..e38e46d 100644
--- a/src/testcases/org/apache/poi/POITestCase.java
+++ b/src/testcases/org/apache/poi/POITestCase.java
@@ -34,6 +34,21 @@
         );
      }
     
+    public static <T> void assertEquals(T[] expected, T[] actual)
+    {
+        assertEquals("Non-matching lengths", expected.length, actual.length);
+        for (int i=0; i<expected.length; i++) {
+            assertEquals("Mis-match at offset " + i, expected[i], actual[i]);
+        }
+    }
+    public static void assertEquals(byte[] expected, byte[] actual)
+    {
+        assertEquals("Non-matching lengths", expected.length, actual.length);
+        for (int i=0; i<expected.length; i++) {
+            assertEquals("Mis-match at offset " + i, expected[i], actual[i]);
+        }
+    }
+    
     public static <T> void assertContains(T needle, T[] haystack)
     {
        // Check
diff --git a/src/testcases/org/apache/poi/TestPOIDocumentMain.java b/src/testcases/org/apache/poi/TestPOIDocumentMain.java
index 6755258..cacca43 100644
--- a/src/testcases/org/apache/poi/TestPOIDocumentMain.java
+++ b/src/testcases/org/apache/poi/TestPOIDocumentMain.java
@@ -26,7 +26,8 @@
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 
 /**
  * Tests that POIDocument correctly loads and saves the common
@@ -72,7 +73,7 @@
 
 	public void testWriteProperties() throws Exception {
 		// Just check we can write them back out into a filesystem
-		POIFSFileSystem outFS = new POIFSFileSystem();
+		NPOIFSFileSystem outFS = new NPOIFSFileSystem();
 		doc.readProperties();
 		doc.writeProperties(outFS);
 
@@ -89,14 +90,14 @@
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
 		// Write them out
-		POIFSFileSystem outFS = new POIFSFileSystem();
+		NPOIFSFileSystem outFS = new NPOIFSFileSystem();
 		doc.readProperties();
 		doc.writeProperties(outFS);
 		outFS.writeFilesystem(baos);
 
 		// Create a new version
 		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-		POIFSFileSystem inFS = new POIFSFileSystem(bais);
+		OPOIFSFileSystem inFS = new OPOIFSFileSystem(bais);
 
 		// Check they're still there
 		doc.directory = inFS.getRoot();
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherDump.java b/src/testcases/org/apache/poi/ddf/TestEscherDump.java
index 5d05bb2..276c15f 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherDump.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherDump.java
@@ -17,8 +17,13 @@
 
 package org.apache.poi.ddf;
 
+import static org.junit.Assert.*;
+
 import java.io.ByteArrayInputStream;
 
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.util.IOUtils;
 import org.junit.Test;
 
 public class TestEscherDump {
@@ -36,4 +41,18 @@
     public void testWithData() throws Exception {
         new EscherDump().dumpOld(8, new ByteArrayInputStream(new byte[] { 00, 00, 00, 00, 00, 00, 00, 00 }), System.out);
     }
+
+    @Test
+    public  void testWithSamplefile() throws Exception {
+        //InputStream stream = HSSFTestDataSamples.openSampleFileStream(")
+        byte[] data = POIDataSamples.getDDFInstance().readFile("Container.dat");
+        new EscherDump().dump(data.length, data, System.out);
+        //new EscherDump().dumpOld(data.length, new ByteArrayInputStream(data), System.out);
+        
+        data = new byte[2586114];
+        int bytes = IOUtils.readFully(HSSFTestDataSamples.openSampleFileStream("44593.xls"), data);
+        assertTrue(bytes != -1);
+        //new EscherDump().dump(bytes, data, System.out);
+        //new EscherDump().dumpOld(bytes, new ByteArrayInputStream(data), System.out);
+    }
 }
diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestHPSFBugs.java b/src/testcases/org/apache/poi/hpsf/basic/TestHPSFBugs.java
index ff9ba87..cd58e15 100644
--- a/src/testcases/org/apache/poi/hpsf/basic/TestHPSFBugs.java
+++ b/src/testcases/org/apache/poi/hpsf/basic/TestHPSFBugs.java
@@ -31,7 +31,7 @@
 import org.apache.poi.hpsf.SummaryInformation;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 
 /**
  * Tests various bugs have been fixed
@@ -109,8 +109,8 @@
     */
    public void test54233() throws Exception {
        DocumentInputStream dis;
-       POIFSFileSystem fs = 
-               new POIFSFileSystem(_samples.openResourceAsStream("TestNon4ByteBoundary.doc"));
+       NPOIFSFileSystem fs = 
+               new NPOIFSFileSystem(_samples.openResourceAsStream("TestNon4ByteBoundary.doc"));
        
        dis = fs.createDocumentInputStream(SummaryInformation.DEFAULT_STREAM_NAME);
        SummaryInformation si = (SummaryInformation)PropertySetFactory.create(dis);
@@ -130,7 +130,7 @@
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        doc.write(baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-       doc = new HPSFPropertiesOnlyDocument(new POIFSFileSystem(bais));
+       doc = new HPSFPropertiesOnlyDocument(new NPOIFSFileSystem(bais));
        
        // Check properties are still there
        assertEquals("Microsoft Word 10.0", si.getApplicationName());
@@ -144,8 +144,8 @@
     */
    public void test56138() throws Exception {
        DocumentInputStream dis;
-       POIFSFileSystem fs = 
-               new POIFSFileSystem(_samples.openResourceAsStream("TestZeroLengthCodePage.mpp"));
+       NPOIFSFileSystem fs = 
+               new NPOIFSFileSystem(_samples.openResourceAsStream("TestZeroLengthCodePage.mpp"));
        
        dis = fs.createDocumentInputStream(SummaryInformation.DEFAULT_STREAM_NAME);
        SummaryInformation si = (SummaryInformation)PropertySetFactory.create(dis);
diff --git a/src/testcases/org/apache/poi/hpsf/extractor/TestHPSFPropertiesExtractor.java b/src/testcases/org/apache/poi/hpsf/extractor/TestHPSFPropertiesExtractor.java
index 22238d7..0ef3971 100644
--- a/src/testcases/org/apache/poi/hpsf/extractor/TestHPSFPropertiesExtractor.java
+++ b/src/testcases/org/apache/poi/hpsf/extractor/TestHPSFPropertiesExtractor.java
@@ -34,45 +34,53 @@
 	public void testNormalProperties() throws Exception {
 		POIFSFileSystem fs = new POIFSFileSystem(_samples.openResourceAsStream("TestMickey.doc"));
 		HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor(fs);
-		ext.getText();
-
-		// Check each bit in turn
-		String sinfText = ext.getSummaryInformationText();
-		String dinfText = ext.getDocumentSummaryInformationText();
-
-		assertTrue(sinfText.indexOf("TEMPLATE = Normal") > -1);
-		assertTrue(sinfText.indexOf("SUBJECT = sample subject") > -1);
-		assertTrue(dinfText.indexOf("MANAGER = sample manager") > -1);
-		assertTrue(dinfText.indexOf("COMPANY = sample company") > -1);
-
-		// Now overall
-		String text = ext.getText();
-		assertTrue(text.indexOf("TEMPLATE = Normal") > -1);
-		assertTrue(text.indexOf("SUBJECT = sample subject") > -1);
-		assertTrue(text.indexOf("MANAGER = sample manager") > -1);
-		assertTrue(text.indexOf("COMPANY = sample company") > -1);
+		try {
+    		ext.getText();
+    
+    		// Check each bit in turn
+    		String sinfText = ext.getSummaryInformationText();
+    		String dinfText = ext.getDocumentSummaryInformationText();
+    
+    		assertTrue(sinfText.indexOf("TEMPLATE = Normal") > -1);
+    		assertTrue(sinfText.indexOf("SUBJECT = sample subject") > -1);
+    		assertTrue(dinfText.indexOf("MANAGER = sample manager") > -1);
+    		assertTrue(dinfText.indexOf("COMPANY = sample company") > -1);
+    
+    		// Now overall
+    		String text = ext.getText();
+    		assertTrue(text.indexOf("TEMPLATE = Normal") > -1);
+    		assertTrue(text.indexOf("SUBJECT = sample subject") > -1);
+    		assertTrue(text.indexOf("MANAGER = sample manager") > -1);
+    		assertTrue(text.indexOf("COMPANY = sample company") > -1);
+		} finally {
+		    ext.close();
+		}
 	}
 
 	public void testNormalUnicodeProperties() throws Exception {
 		POIFSFileSystem fs = new POIFSFileSystem(_samples.openResourceAsStream("TestUnicode.xls"));
 		HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor(fs);
-		ext.getText();
-
-		// Check each bit in turn
-		String sinfText = ext.getSummaryInformationText();
-		String dinfText = ext.getDocumentSummaryInformationText();
-
-		assertTrue(sinfText.indexOf("AUTHOR = marshall") > -1);
-		assertTrue(sinfText.indexOf("TITLE = Titel: \u00c4h") > -1);
-		assertTrue(dinfText.indexOf("COMPANY = Schreiner") > -1);
-		assertTrue(dinfText.indexOf("SCALE = false") > -1);
-
-		// Now overall
-		String text = ext.getText();
-		assertTrue(text.indexOf("AUTHOR = marshall") > -1);
-		assertTrue(text.indexOf("TITLE = Titel: \u00c4h") > -1);
-		assertTrue(text.indexOf("COMPANY = Schreiner") > -1);
-		assertTrue(text.indexOf("SCALE = false") > -1);
+		try {
+    		ext.getText();
+    
+    		// Check each bit in turn
+    		String sinfText = ext.getSummaryInformationText();
+    		String dinfText = ext.getDocumentSummaryInformationText();
+    
+    		assertTrue(sinfText.indexOf("AUTHOR = marshall") > -1);
+    		assertTrue(sinfText.indexOf("TITLE = Titel: \u00c4h") > -1);
+    		assertTrue(dinfText.indexOf("COMPANY = Schreiner") > -1);
+    		assertTrue(dinfText.indexOf("SCALE = false") > -1);
+    
+    		// Now overall
+    		String text = ext.getText();
+    		assertTrue(text.indexOf("AUTHOR = marshall") > -1);
+    		assertTrue(text.indexOf("TITLE = Titel: \u00c4h") > -1);
+    		assertTrue(text.indexOf("COMPANY = Schreiner") > -1);
+    		assertTrue(text.indexOf("SCALE = false") > -1);
+		} finally {
+		    ext.close();
+		}
 	}
 
 	public void testCustomProperties() throws Exception {
@@ -80,18 +88,21 @@
 				_samples.openResourceAsStream("TestMickey.doc")
 		);
 		HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor(fs);
-
-		// Custom properties are part of the document info stream
-		String dinfText = ext.getDocumentSummaryInformationText();
-		assertTrue(dinfText.indexOf("Client = sample client") > -1);
-		assertTrue(dinfText.indexOf("Division = sample division") > -1);
-
-		String text = ext.getText();
-		assertTrue(text.indexOf("Client = sample client") > -1);
-		assertTrue(text.indexOf("Division = sample division") > -1);
+		try {
+    		// Custom properties are part of the document info stream
+    		String dinfText = ext.getDocumentSummaryInformationText();
+    		assertTrue(dinfText.indexOf("Client = sample client") > -1);
+    		assertTrue(dinfText.indexOf("Division = sample division") > -1);
+    
+    		String text = ext.getText();
+    		assertTrue(text.indexOf("Client = sample client") > -1);
+    		assertTrue(text.indexOf("Division = sample division") > -1);
+        } finally {
+            ext.close();
+        }
 	}
 
-	public void testConstructors() {
+	public void testConstructors() throws IOException {
 		POIFSFileSystem fs;
 		HSSFWorkbook wb;
 		try {
@@ -102,9 +113,29 @@
 		}
 		ExcelExtractor excelExt = new ExcelExtractor(wb);
 
-		String fsText = (new HPSFPropertiesExtractor(fs)).getText();
-		String hwText = (new HPSFPropertiesExtractor(wb)).getText();
-		String eeText = (new HPSFPropertiesExtractor(excelExt)).getText();
+		final String fsText;
+		HPSFPropertiesExtractor fsExt = new HPSFPropertiesExtractor(fs);
+		try {
+		    fsText = fsExt.getText();
+		} finally {
+		    fsExt.close();
+		}
+        
+        final String hwText; 
+		HPSFPropertiesExtractor hwExt = new HPSFPropertiesExtractor(wb);
+		try {
+		    hwText = hwExt.getText();
+		} finally {
+		    hwExt.close();
+		}
+		
+        final String eeText;
+        HPSFPropertiesExtractor eeExt = new HPSFPropertiesExtractor(excelExt);
+        try {
+            eeText = eeExt.getText();
+        } finally {
+            eeExt.close();
+        }
 
 		assertEquals(fsText, hwText);
 		assertEquals(fsText, eeText);
@@ -113,13 +144,17 @@
 		assertTrue(fsText.indexOf("TITLE = Titel: \u00c4h") > -1);
 	}
 
-	public void test42726() {
-		HPSFPropertiesExtractor ex = new HPSFPropertiesExtractor(HSSFTestDataSamples.openSampleWorkbook("42726.xls"));
-		String txt = ex.getText();
-		assertTrue(txt.indexOf("PID_AUTHOR") != -1);
-		assertTrue(txt.indexOf("PID_EDITTIME") != -1);
-		assertTrue(txt.indexOf("PID_REVNUMBER") != -1);
-		assertTrue(txt.indexOf("PID_THUMBNAIL") != -1);
+	public void test42726() throws IOException {
+		HPSFPropertiesExtractor ext = new HPSFPropertiesExtractor(HSSFTestDataSamples.openSampleWorkbook("42726.xls"));
+		try {
+    		String txt = ext.getText();
+    		assertTrue(txt.indexOf("PID_AUTHOR") != -1);
+    		assertTrue(txt.indexOf("PID_EDITTIME") != -1);
+    		assertTrue(txt.indexOf("PID_REVNUMBER") != -1);
+    		assertTrue(txt.indexOf("PID_THUMBNAIL") != -1);
+        } finally {
+            ext.close();
+        }
 	}
 	
     public void testThumbnail() throws Exception {
diff --git a/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java b/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java
index 51cc0ed..d544b0b 100644
--- a/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java
+++ b/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf;
 
+import java.io.InputStream;
+
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -38,6 +40,9 @@
     public HSSFWorkbook openSampleWorkbook(String sampleFileName) {
         return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
     }
+    public InputStream openWorkbookStream(String sampleFileName) {
+        return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
+    }
     
     public HSSFWorkbook writeOutAndReadBack(Workbook original) {
         if(!(original instanceof HSSFWorkbook)) {
diff --git a/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java b/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java
index 521b9ad..0adb2cf 100644
--- a/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java
+++ b/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java
@@ -79,11 +79,11 @@
 			try {
 				runOneFile(dir, file, failed);
 			} catch (Exception e) {
-				System.out.println("Failed: " + file);
 				if(SILENT_EXCLUDED.contains(file)) {
 					continue;
 				}
 
+				System.out.println("Failed: " + file);
 				e.printStackTrace();
 				
 				// try to read it in HSSFWorkbook to quickly fail if we cannot read the file there at all and thus probably can use SILENT_EXCLUDED instead
diff --git a/src/testcases/org/apache/poi/hssf/eventusermodel/TestHSSFEventFactory.java b/src/testcases/org/apache/poi/hssf/eventusermodel/TestHSSFEventFactory.java
index 9766331..0a111be 100644
--- a/src/testcases/org/apache/poi/hssf/eventusermodel/TestHSSFEventFactory.java
+++ b/src/testcases/org/apache/poi/hssf/eventusermodel/TestHSSFEventFactory.java
@@ -22,107 +22,182 @@
 
 import junit.framework.TestCase;
 
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.BoundSheetRecord;
 import org.apache.poi.hssf.record.ContinueRecord;
 import org.apache.poi.hssf.record.DVALRecord;
 import org.apache.poi.hssf.record.DVRecord;
 import org.apache.poi.hssf.record.EOFRecord;
 import org.apache.poi.hssf.record.FeatHdrRecord;
+import org.apache.poi.hssf.record.NumberRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.SelectionRecord;
 import org.apache.poi.hssf.record.WindowTwoRecord;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
 /**
- * 
+ * Testing for {@link HSSFEventFactory}
  */
 public final class TestHSSFEventFactory extends TestCase {
-	
-	private static final InputStream openSample(String sampleFileName) {
-		return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
-	}
+    private static final InputStream openSample(String sampleFileName) {
+        return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
+    }
 
-	public void testWithMissingRecords() throws Exception {
+    public void testWithMissingRecords() throws Exception {
 
-		HSSFRequest req = new HSSFRequest();
-		MockHSSFListener mockListen = new MockHSSFListener();
-		req.addListenerForAllRecords(mockListen);
-		
-		POIFSFileSystem fs = new POIFSFileSystem(openSample("SimpleWithSkip.xls"));
-		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
+        HSSFRequest req = new HSSFRequest();
+        MockHSSFListener mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
 
-		Record[] recs = mockListen.getRecords();
-		// Check we got the records
-		assertTrue( recs.length > 100 );
-		
-		// Check that the last few records are as we expect
-		// (Makes sure we don't accidently skip the end ones)
-		int numRec = recs.length;
-		assertEquals(WindowTwoRecord.class, recs[numRec-3].getClass());
-		assertEquals(SelectionRecord.class, recs[numRec-2].getClass());
-		assertEquals(EOFRecord.class,	   recs[numRec-1].getClass());
-	}
+        POIFSFileSystem fs = new POIFSFileSystem(openSample("SimpleWithSkip.xls"));
+        HSSFEventFactory factory = new HSSFEventFactory();
+        factory.processWorkbookEvents(req, fs);
 
-	public void testWithCrazyContinueRecords() throws Exception {
-		// Some files have crazy ordering of their continue records
-		// Check that we don't break on them (bug #42844)
-		
-		HSSFRequest req = new HSSFRequest();
-		MockHSSFListener mockListen = new MockHSSFListener();
-		req.addListenerForAllRecords(mockListen);
-		
-		POIFSFileSystem fs = new POIFSFileSystem(openSample("ContinueRecordProblem.xls"));
-		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
+        Record[] recs = mockListen.getRecords();
+        // Check we got the records
+        assertTrue( recs.length > 100 );
 
-		Record[] recs = mockListen.getRecords();
-		// Check we got the records
-		assertTrue( recs.length > 100 );
+        // Check that the last few records are as we expect
+        // (Makes sure we don't accidently skip the end ones)
+        int numRec = recs.length;
+        assertEquals(WindowTwoRecord.class, recs[numRec-3].getClass());
+        assertEquals(SelectionRecord.class, recs[numRec-2].getClass());
+        assertEquals(EOFRecord.class,	   recs[numRec-1].getClass());
+    }
 
-		// And none of them are continue ones
-		for(int i=0; i<recs.length; i++) {
-			assertFalse( recs[i] instanceof ContinueRecord );
-		}
-		
-		// Check that the last few records are as we expect
-		// (Makes sure we don't accidently skip the end ones)
-		int numRec = recs.length;
-		assertEquals(DVALRecord.class,    recs[numRec-4].getClass());
-		assertEquals(DVRecord.class,      recs[numRec-3].getClass());
-		assertEquals(FeatHdrRecord.class, recs[numRec-2].getClass());
-		assertEquals(EOFRecord.class,     recs[numRec-1].getClass());
-	}
+    public void testWithCrazyContinueRecords() throws Exception {
+        // Some files have crazy ordering of their continue records
+        // Check that we don't break on them (bug #42844)
 
-	/**
-	 * Unknown records can be continued.
-	 * Check that HSSFEventFactory doesn't break on them.
-	 * (the test file was provided in a reopen of bug #42844)
-	 */
-	public void testUnknownContinueRecords() throws Exception {
+        HSSFRequest req = new HSSFRequest();
+        MockHSSFListener mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
 
-		HSSFRequest req = new HSSFRequest();
-		MockHSSFListener mockListen = new MockHSSFListener();
-		req.addListenerForAllRecords(mockListen);
+        POIFSFileSystem fs = new POIFSFileSystem(openSample("ContinueRecordProblem.xls"));
+        HSSFEventFactory factory = new HSSFEventFactory();
+        factory.processWorkbookEvents(req, fs);
 
-		POIFSFileSystem fs = new POIFSFileSystem(openSample("42844.xls"));
-		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
+        Record[] recs = mockListen.getRecords();
+        // Check we got the records
+        assertTrue( recs.length > 100 );
 
-		assertTrue("no errors while processing the file", true);
-	}
+        // And none of them are continue ones
+        for(int i=0; i<recs.length; i++) {
+            assertFalse( recs[i] instanceof ContinueRecord );
+        }
 
-	private static class MockHSSFListener implements HSSFListener {
-		private final List<Record> records = new ArrayList<Record>();
+        // Check that the last few records are as we expect
+        // (Makes sure we don't accidently skip the end ones)
+        int numRec = recs.length;
+        assertEquals(DVALRecord.class,    recs[numRec-4].getClass());
+        assertEquals(DVRecord.class,      recs[numRec-3].getClass());
+        assertEquals(FeatHdrRecord.class, recs[numRec-2].getClass());
+        assertEquals(EOFRecord.class,     recs[numRec-1].getClass());
+    }
 
-		public MockHSSFListener() {}
-		public Record[] getRecords() {
-			Record[] result = new Record[records.size()];
-			records.toArray(result);
-			return result;
-		}
+    /**
+     * Unknown records can be continued.
+     * Check that HSSFEventFactory doesn't break on them.
+     * (the test file was provided in a reopen of bug #42844)
+     */
+    public void testUnknownContinueRecords() throws Exception {
 
-		public void processRecord(Record record) {
-			records.add(record);
-		}
-	}
+        HSSFRequest req = new HSSFRequest();
+        MockHSSFListener mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
+
+        POIFSFileSystem fs = new POIFSFileSystem(openSample("42844.xls"));
+        HSSFEventFactory factory = new HSSFEventFactory();
+        factory.processWorkbookEvents(req, fs);
+    }
+
+    private static class MockHSSFListener implements HSSFListener {
+        private final List<Record> records = new ArrayList<Record>();
+
+        public MockHSSFListener() {}
+        public Record[] getRecords() {
+            Record[] result = new Record[records.size()];
+            records.toArray(result);
+            return result;
+        }
+
+        public void processRecord(Record record) {
+            records.add(record);
+        }
+    }
+
+    public void testWithDifferentWorkbookName() throws Exception {
+        HSSFRequest req = new HSSFRequest();
+        MockHSSFListener mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
+
+        POIFSFileSystem fs = new POIFSFileSystem(openSample("BOOK_in_capitals.xls"));
+        HSSFEventFactory factory = new HSSFEventFactory();
+        factory.processWorkbookEvents(req, fs);
+
+        fs = new POIFSFileSystem(openSample("WORKBOOK_in_capitals.xls"));
+        factory = new HSSFEventFactory();
+        factory.processWorkbookEvents(req, fs);
+    }
+
+    public void testWithPasswordProtectedWorkbooks() throws Exception {
+        HSSFRequest req = new HSSFRequest();
+        MockHSSFListener mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
+
+        // Without a password, can't be read
+        Biff8EncryptionKey.setCurrentUserPassword(null);
+        POIFSFileSystem fs = new POIFSFileSystem(openSample("xor-encryption-abc.xls"));
+
+        HSSFEventFactory factory = new HSSFEventFactory();
+        try {
+            factory.processWorkbookEvents(req, fs);
+            fail("Shouldn't be able to process protected workbook without the password");
+        } catch (EncryptedDocumentException e) {}
+
+
+        // With the password, is properly processed
+        Biff8EncryptionKey.setCurrentUserPassword("abc");
+
+        req = new HSSFRequest();
+        mockListen = new MockHSSFListener();
+        req.addListenerForAllRecords(mockListen);
+        factory.processWorkbookEvents(req, fs);
+
+        // Check we got the sheet and the contents
+        Record[] recs = mockListen.getRecords();
+        assertTrue( recs.length > 50 );
+
+        // Has one sheet, with values 1,2,3 in column A rows 1-3
+        boolean hasSheet=false, hasA1=false, hasA2=false, hasA3=false;
+        for (Record r : recs) {
+            if (r instanceof BoundSheetRecord) {
+                BoundSheetRecord bsr = (BoundSheetRecord)r;
+                assertEquals("Sheet1", bsr.getSheetname());
+                hasSheet = true;
+            }
+            if (r instanceof NumberRecord) {
+                NumberRecord nr = (NumberRecord)r;
+                if (nr.getColumn() == 0 && nr.getRow() == 0) {
+                    assertEquals(1, (int)nr.getValue());
+                    hasA1 = true;
+                }
+                if (nr.getColumn() == 0 && nr.getRow() == 1) {
+                    assertEquals(2, (int)nr.getValue());
+                    hasA2 = true;
+                }
+                if (nr.getColumn() == 0 && nr.getRow() == 2) {
+                    assertEquals(3, (int)nr.getValue());
+                    hasA3 = true;
+                }
+            }
+        }
+
+        assertTrue("Sheet record not found", hasSheet);
+        assertTrue("Numeric record for A1 not found", hasA1);
+        assertTrue("Numeric record for A2 not found", hasA2);
+        assertTrue("Numeric record for A3 not found", hasA3);
+    }
 }	
diff --git a/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java b/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java
index de82210..793215a 100644
--- a/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java
+++ b/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java
@@ -46,15 +46,18 @@
 	}
 
 
-	public void testSimple() {
-
+	public void testSimple() throws IOException {
 		ExcelExtractor extractor = createExtractor("Simple.xls");
 
-		assertEquals("Sheet1\nreplaceMe\nSheet2\nSheet3\n", extractor.getText());
-
-		// Now turn off sheet names
-		extractor.setIncludeSheetNames(false);
-		assertEquals("replaceMe\n", extractor.getText());
+		try {
+    		assertEquals("Sheet1\nreplaceMe\nSheet2\nSheet3\n", extractor.getText());
+    
+    		// Now turn off sheet names
+    		extractor.setIncludeSheetNames(false);
+    		assertEquals("replaceMe\n", extractor.getText());
+		} finally {
+		    extractor.close();
+		}
 	}
 
 	public void testNumericFormula() {
@@ -126,45 +129,47 @@
 
 
 	public void testEventExtractor() throws Exception {
-		EventBasedExcelExtractor extractor;
-
 		// First up, a simple file with string
 		//  based formulas in it
-		extractor = new EventBasedExcelExtractor(
+		EventBasedExcelExtractor extractor = new EventBasedExcelExtractor(
 				new POIFSFileSystem(
 						HSSFTestDataSamples.openSampleFileStream("SimpleWithFormula.xls")
 				)
 		);
-		extractor.setIncludeSheetNames(true);
-
-		String text = extractor.getText();
-		assertEquals("Sheet1\nreplaceme\nreplaceme\nreplacemereplaceme\nSheet2\nSheet3\n", text);
-
-		extractor.setIncludeSheetNames(false);
-		extractor.setFormulasNotResults(true);
-
-		text = extractor.getText();
-		assertEquals("replaceme\nreplaceme\nCONCATENATE(A1,A2)\n", text);
-
-
-		// Now, a slightly longer file with numeric formulas
-		extractor = new EventBasedExcelExtractor(
-				new POIFSFileSystem(
-						HSSFTestDataSamples.openSampleFileStream("sumifformula.xls")
-				)
-		);
-		extractor.setIncludeSheetNames(false);
-		extractor.setFormulasNotResults(true);
-
-		text = extractor.getText();
-		assertEquals(
-				"1000\t1\tSUMIF(A1:A5,\">4000\",B1:B5)\n" +
-				"2000\t2\n" +
-				"3000\t3\n" +
-				"4000\t4\n" +
-				"5000\t5\n",
-				text
-		);
+		try {
+    		extractor.setIncludeSheetNames(true);
+    
+    		String text = extractor.getText();
+    		assertEquals("Sheet1\nreplaceme\nreplaceme\nreplacemereplaceme\nSheet2\nSheet3\n", text);
+    
+    		extractor.setIncludeSheetNames(false);
+    		extractor.setFormulasNotResults(true);
+    
+    		text = extractor.getText();
+    		assertEquals("replaceme\nreplaceme\nCONCATENATE(A1,A2)\n", text);
+    
+    
+    		// Now, a slightly longer file with numeric formulas
+    		extractor = new EventBasedExcelExtractor(
+    				new POIFSFileSystem(
+    						HSSFTestDataSamples.openSampleFileStream("sumifformula.xls")
+    				)
+    		);
+    		extractor.setIncludeSheetNames(false);
+    		extractor.setFormulasNotResults(true);
+    
+    		text = extractor.getText();
+    		assertEquals(
+    				"1000\t1\tSUMIF(A1:A5,\">4000\",B1:B5)\n" +
+    				"2000\t2\n" +
+    				"3000\t3\n" +
+    				"4000\t4\n" +
+    				"5000\t5\n",
+    				text
+    		);
+		} finally {
+		    extractor.close();
+		}
 	}
 
 	public void testWithComments() {
@@ -272,15 +277,22 @@
 		HSSFWorkbook wbB = new HSSFWorkbook(dirB, fs, true);
 
 		ExcelExtractor exA = new ExcelExtractor(wbA);
-		ExcelExtractor exB = new ExcelExtractor(wbB);
-
-		assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n",
-				exA.getText());
-		assertEquals("Sample Excel", exA.getSummaryInformation().getTitle());
-
-		assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n",
-				exB.getText());
-		assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle());
+		try {
+    		ExcelExtractor exB = new ExcelExtractor(wbB);
+    		try {
+        		assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n",
+        				exA.getText());
+        		assertEquals("Sample Excel", exA.getSummaryInformation().getTitle());
+        
+        		assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n",
+        				exB.getText());
+        		assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle());
+    		} finally {
+    		    exB.close();
+    		}
+		} finally {
+		    exA.close();
+		}
 	}
 
 	/**
@@ -299,21 +311,32 @@
 		HSSFWorkbook wbB = new HSSFWorkbook(dirB, fs, true);
 
 		ExcelExtractor exA = new ExcelExtractor(wbA);
-		ExcelExtractor exB = new ExcelExtractor(wbB);
-
-		assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n",
-				exA.getText());
-		assertEquals("Sample Excel", exA.getSummaryInformation().getTitle());
-
-		assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n",
-				exB.getText());
-		assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle());
-
-		// And the base file too
-		ExcelExtractor ex = new ExcelExtractor(fs);
-		assertEquals("Sheet1\nI have lots of embeded files in me\nSheet2\nSheet3\n",
-				ex.getText());
-		assertEquals("Excel With Embeded", ex.getSummaryInformation().getTitle());
+		try {
+    		ExcelExtractor exB = new ExcelExtractor(wbB);
+    		try {
+        		assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n",
+        				exA.getText());
+        		assertEquals("Sample Excel", exA.getSummaryInformation().getTitle());
+        
+        		assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n",
+        				exB.getText());
+        		assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle());
+        
+        		// And the base file too
+        		ExcelExtractor ex = new ExcelExtractor(fs);
+        		try {
+            		assertEquals("Sheet1\nI have lots of embeded files in me\nSheet2\nSheet3\n",
+            				ex.getText());
+            		assertEquals("Excel With Embeded", ex.getSummaryInformation().getTitle());
+        		} finally {
+        		    ex.close();
+        		}
+            } finally {
+                exB.close();
+            }
+        } finally {
+            exA.close();
+        }
 	}
 
 	/**
@@ -340,4 +363,10 @@
 
 		assertTrue(text.contains("ZIP"));
 	}
+
+	public void testNullPointerException() {
+		ExcelExtractor extractor = createExtractor("ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls");
+		assertNotNull(extractor);
+		assertNotNull(extractor.getText());
+	}
 }
diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
index ca8e255..c62c365 100644
--- a/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
+++ b/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
@@ -51,8 +51,6 @@
  * @author Evgeniy Berlog

  */

 public class TestDrawingAggregate extends TestCase {

-

-

     /**

      *  information about drawing aggregate in a worksheet

      */

@@ -189,7 +187,15 @@
                 // System.out.println("[WARN]  Cannot read " + file.getName());

                 continue;

             }

-            assertWriteAndReadBack(wb);

+            try {

+                assertWriteAndReadBack(wb);

+            } catch (Exception e) {

+                String filename = file.getName();

+                System.out.println("Drawing Aggregate re-write test failed for " + filename);

+                e.printStackTrace(System.out);

+                

+                fail("Error when writing and re-reading workbook " + filename + "\n" + e);

+            }

         }

     }

 

diff --git a/src/testcases/org/apache/poi/hssf/model/TestShapes.java b/src/testcases/org/apache/poi/hssf/model/TestShapes.java
index d17178e..beed4a1 100644
--- a/src/testcases/org/apache/poi/hssf/model/TestShapes.java
+++ b/src/testcases/org/apache/poi/hssf/model/TestShapes.java
@@ -20,6 +20,7 @@
 package org.apache.poi.hssf.model;
 
 import junit.framework.TestCase;
+
 import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
 import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
 import org.apache.poi.hssf.usermodel.HSSFComment;
@@ -37,7 +38,8 @@
      *
      * See Bug 51332
      */
-    public void testShapeId(){
+    @SuppressWarnings("deprecation")
+	public void testShapeId(){
 
         HSSFClientAnchor anchor = new HSSFClientAnchor();
         AbstractShape shape;
diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java
index 239f209..9c9b548 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java
@@ -23,16 +23,11 @@
 import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
- * Tests the serialization and deserialization of the TestCFHeaderRecord
- * class works correctly.  
- *
- * @author Dmitriy Kumshayev 
+ * Tests the serialization and deserialization of the {@link CFHeaderRecord}
+ *  and {@link CFHeader12Record} classes works correctly.  
  */
-public final class TestCFHeaderRecord extends TestCase
-{
-
-	public void testCreateCFHeaderRecord () 
-	{
+public final class TestCFHeaderRecord extends TestCase {
+	public void testCreateCFHeaderRecord () {
 		CFHeaderRecord record = new CFHeaderRecord();
 		CellRangeAddress[] ranges = {
 			new CellRangeAddress(0,0xFFFF,5,5),
@@ -50,12 +45,52 @@
 		assertEquals(65535, enclosingCellRange.getLastRow());
 		assertEquals(0, enclosingCellRange.getFirstColumn());
 		assertEquals(6, enclosingCellRange.getLastColumn());
+		
+		assertEquals(false, record.getNeedRecalculation());
+		assertEquals(0, record.getID());
+		
 		record.setNeedRecalculation(true);
-		assertTrue(record.getNeedRecalculation());
+        assertEquals(true, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setID(7);
 		record.setNeedRecalculation(false);
-		assertFalse(record.getNeedRecalculation());
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(7, record.getID());
 	}
 	
+    public void testCreateCFHeader12Record () {
+        CFHeader12Record record = new CFHeader12Record();
+        CellRangeAddress[] ranges = {
+            new CellRangeAddress(0,0xFFFF,5,5),
+            new CellRangeAddress(0,0xFFFF,6,6),
+            new CellRangeAddress(0,1,0,1),
+            new CellRangeAddress(0,1,2,3),
+            new CellRangeAddress(2,3,0,1),
+            new CellRangeAddress(2,3,2,3),
+        };
+        record.setCellRanges(ranges);
+        ranges = record.getCellRanges();
+        assertEquals(6,ranges.length);
+        CellRangeAddress enclosingCellRange = record.getEnclosingCellRange();
+        assertEquals(0, enclosingCellRange.getFirstRow());
+        assertEquals(65535, enclosingCellRange.getLastRow());
+        assertEquals(0, enclosingCellRange.getFirstColumn());
+        assertEquals(6, enclosingCellRange.getLastColumn());
+
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setNeedRecalculation(true);
+        assertEquals(true, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setID(7);
+        record.setNeedRecalculation(false);
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(7, record.getID());
+    }
+    
 	public void testSerialization() {
 		byte[] recordData = 
 		{
diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java
index c5da218..c39e3e4 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java
@@ -21,7 +21,8 @@
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
+import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
 import org.apache.poi.hssf.record.cf.FontFormatting;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
@@ -31,14 +32,15 @@
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.RefNPtg;
 import org.apache.poi.ss.formula.ptg.RefPtg;
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
 import org.apache.poi.util.LittleEndian;
 
 /**
  * Tests the serialization and deserialization of the TestCFRuleRecord
  * class works correctly.
- *
- * @author Dmitriy Kumshayev
  */
+@SuppressWarnings("resource")
 public final class TestCFRuleRecord extends TestCase {
     public void testConstructors () {
         HSSFWorkbook workbook = new HSSFWorkbook();
@@ -91,19 +93,77 @@
         }
     }
 
+    public void testCreateCFRule12Record() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        HSSFSheet sheet = workbook.createSheet();
+        CFRule12Record record = CFRule12Record.create(sheet, "7");
+        testCFRule12Record(record);
+
+        // Serialize
+        byte [] serializedRecord = record.serialize();
+
+        // Strip header
+        byte [] recordData = new byte[serializedRecord.length-4];
+        System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
+
+        // Deserialize
+        record = new CFRule12Record(TestcaseRecordInputStream.create(CFRule12Record.sid, recordData));
+
+        // Serialize again
+        byte[] output = record.serialize();
+
+        // Compare
+        assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
+
+        for (int i = 0; i < recordData.length;i++)
+        {
+            assertEquals("CFRule12Record doesn't match", recordData[i], output[i+4]);
+        }
+    }
+
+    public void testCreateIconCFRule12Record() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        HSSFSheet sheet = workbook.createSheet();
+        CFRule12Record record = CFRule12Record.create(sheet, IconSet.GREY_5_ARROWS);
+        record.getMultiStateFormatting().getThresholds()[1].setType(RangeType.PERCENT.id);
+        record.getMultiStateFormatting().getThresholds()[1].setValue(10d);
+        record.getMultiStateFormatting().getThresholds()[2].setType(RangeType.NUMBER.id);
+        record.getMultiStateFormatting().getThresholds()[2].setValue(-4d);
+        
+        // Check it 
+        testCFRule12Record(record);
+        assertEquals(IconSet.GREY_5_ARROWS, record.getMultiStateFormatting().getIconSet());
+        assertEquals(5, record.getMultiStateFormatting().getThresholds().length);
+
+        // Serialize
+        byte [] serializedRecord = record.serialize();
+
+        // Strip header
+        byte [] recordData = new byte[serializedRecord.length-4];
+        System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
+
+        // Deserialize
+        record = new CFRule12Record(TestcaseRecordInputStream.create(CFRule12Record.sid, recordData));
+        
+        // Check it has the icon, and the right number of thresholds
+        assertEquals(IconSet.GREY_5_ARROWS, record.getMultiStateFormatting().getIconSet());
+        assertEquals(5, record.getMultiStateFormatting().getThresholds().length);
+
+        // Serialize again
+        byte[] output = record.serialize();
+
+        // Compare
+        assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
+
+        for (int i = 0; i < recordData.length;i++)
+        {
+            assertEquals("CFRule12Record doesn't match", recordData[i], output[i+4]);
+        }
+    }
+    
     private void testCFRuleRecord(CFRuleRecord record) {
-        FontFormatting fontFormatting = new FontFormatting();
-        testFontFormattingAccessors(fontFormatting);
-        assertFalse(record.containsFontFormattingBlock());
-        record.setFontFormatting(fontFormatting);
-        assertTrue(record.containsFontFormattingBlock());
-
-        BorderFormatting borderFormatting = new BorderFormatting();
-        testBorderFormattingAccessors(borderFormatting);
-        assertFalse(record.containsBorderFormattingBlock());
-        record.setBorderFormatting(borderFormatting);
-        assertTrue(record.containsBorderFormattingBlock());
-
+        testCFRuleBase(record);
+        
         assertFalse(record.isLeftBorderModified());
         record.setLeftBorderModified(true);
         assertTrue(record.isLeftBorderModified());
@@ -129,12 +189,6 @@
         assertTrue(record.isBottomLeftTopRightBorderModified());
 
 
-        PatternFormatting patternFormatting = new PatternFormatting();
-        testPatternFormattingAccessors(patternFormatting);
-        assertFalse(record.containsPatternFormattingBlock());
-        record.setPatternFormatting(patternFormatting);
-        assertTrue(record.containsPatternFormattingBlock());
-
         assertFalse(record.isPatternBackgroundColorModified());
         record.setPatternBackgroundColorModified(true);
         assertTrue(record.isPatternBackgroundColorModified());
@@ -147,6 +201,30 @@
         record.setPatternStyleModified(true);
         assertTrue(record.isPatternStyleModified());
     }
+    private void testCFRule12Record(CFRule12Record record) {
+        assertEquals(CFRule12Record.sid, record.getFutureRecordType());
+        assertEquals("A1", record.getAssociatedRange().formatAsString());
+        testCFRuleBase(record);
+    }
+    private void testCFRuleBase(CFRuleBase record) {
+        FontFormatting fontFormatting = new FontFormatting();
+        testFontFormattingAccessors(fontFormatting);
+        assertFalse(record.containsFontFormattingBlock());
+        record.setFontFormatting(fontFormatting);
+        assertTrue(record.containsFontFormattingBlock());
+
+        BorderFormatting borderFormatting = new BorderFormatting();
+        testBorderFormattingAccessors(borderFormatting);
+        assertFalse(record.containsBorderFormattingBlock());
+        record.setBorderFormatting(borderFormatting);
+        assertTrue(record.containsBorderFormattingBlock());
+
+        PatternFormatting patternFormatting = new PatternFormatting();
+        testPatternFormattingAccessors(patternFormatting);
+        assertFalse(record.containsPatternFormattingBlock());
+        record.setPatternFormatting(patternFormatting);
+        assertTrue(record.containsPatternFormattingBlock());
+    }
 
     private void testPatternFormattingAccessors(PatternFormatting patternFormatting) {
         patternFormatting.setFillBackgroundColor(HSSFColor.GREEN.index);
@@ -365,4 +443,11 @@
         byte [] serializedClone = clone.serialize();
         assertArrayEquals(serializedRecord, serializedClone);
     }
+    
+    public void testBug57231_rewrite() {
+        HSSFWorkbook wb = HSSFITestDataProvider.instance.openSampleWorkbook("57231_MixedGasReport.xls");
+        assertEquals(7, wb.getNumberOfSheets());
+        wb = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+        assertEquals(7, wb.getNumberOfSheets());
+    }
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/TestNameRecord.java b/src/testcases/org/apache/poi/hssf/record/TestNameRecord.java
index 28bfb35..231b6c9 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestNameRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestNameRecord.java
@@ -17,15 +17,19 @@
 
 package org.apache.poi.hssf.record;
 
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
 import org.apache.poi.hssf.usermodel.HSSFName;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
 import org.apache.poi.ss.formula.ptg.ArrayPtg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
 import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
 import org.apache.poi.util.HexRead;
 
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
 /**
  * Tests the NameRecord serializes/deserializes correctly
  * 
@@ -60,7 +64,8 @@
 		byte[] data2 = nr.serialize();
 		TestcaseRecordInputStream.confirmRecordEncoding(NameRecord.sid, data, data2);
 	}
-	public void testFormulaRelAbs_bug46174() {
+
+	public void testFormulaRelAbs_bug46174() throws IOException {
 		// perhaps this testcase belongs on TestHSSFName
 		HSSFWorkbook wb = new HSSFWorkbook();
 		HSSFName name = wb.createName();
@@ -68,11 +73,13 @@
 		name.setNameName("test");
 		name.setRefersToFormula("Sheet1!$B$3");
 		if (name.getRefersToFormula().equals("Sheet1!B3")) {
-			throw new AssertionFailedError("Identified bug 46174");
+			fail("Identified bug 46174");
 		}
 		assertEquals("Sheet1!$B$3", name.getRefersToFormula());
+	    wb.close();
 	}
-	public void testFormulaGeneral() {
+
+	public void testFormulaGeneral() throws IOException {
 		// perhaps this testcase belongs on TestHSSFName
 		HSSFWorkbook wb = new HSSFWorkbook();
 		HSSFName name = wb.createName();
@@ -82,6 +89,8 @@
 		assertEquals("Sheet1!A1+Sheet1!A2", name.getRefersToFormula());
 		name.setRefersToFormula("5*6");
 		assertEquals("5*6", name.getRefersToFormula());
+		
+		wb.close();
 	}
 
     /**
@@ -687,4 +696,22 @@
         assertEquals("1.T20.001", vals[0][0]);
         assertEquals("1.T20.010", vals[vals.length - 1][0]);
     }
+
+    public void testBug57923() {
+        NameRecord record = new NameRecord();
+        assertEquals(0, record.getExternSheetNumber());
+        
+        record.setNameDefinition(new Ptg[] {});
+        assertEquals(0, record.getExternSheetNumber());
+        
+        record.setNameDefinition(new Ptg[] {new NamePtg(1)});
+        assertEquals(0, record.getExternSheetNumber());
+
+        record.setNameDefinition(new Ptg[] {new Area3DPtg("area", 1)});
+        assertEquals(1, record.getExternSheetNumber());
+
+        record.setNameDefinition(new Ptg[] {new Ref3DPtg("A1", 1)});
+        assertEquals(1, record.getExternSheetNumber());
+    }
+    
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/TestRecordInputStream.java b/src/testcases/org/apache/poi/hssf/record/TestRecordInputStream.java
index 2b236e1..518c5f0 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestRecordInputStream.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestRecordInputStream.java
@@ -94,4 +94,12 @@
 		String actual = in.readString();
 		assertEquals("Multilingual - \u591A\u8A00\u8A9E", actual);
 	}
+
+	public void testLeftoverDataException() {
+	    // just ensure that the exception is created correctly, even with unknown sids
+	    new RecordInputStream.LeftoverDataException(1, 200);
+	    new RecordInputStream.LeftoverDataException(0, 200);
+        new RecordInputStream.LeftoverDataException(999999999, 200);
+	    new RecordInputStream.LeftoverDataException(HeaderRecord.sid, 200);
+	}
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java
index 1e153bc..c58f401 100644
--- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java
+++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java
@@ -26,107 +26,133 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.CFHeaderBase;
 import org.apache.poi.hssf.record.CFHeaderRecord;
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.CFRuleBase;
+import org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator;
 import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordFactory;
-import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.LittleEndian;
 
 /**
  * Tests the serialization and deserialization of the CFRecordsAggregate
  * class works correctly.  
- *
- * @author Dmitriy Kumshayev 
  */
-public final class TestCFRecordsAggregate extends TestCase
-{
-
-	public void testCFRecordsAggregate() 
-	{
-		HSSFWorkbook workbook = new HSSFWorkbook();
+@SuppressWarnings("resource")
+public final class TestCFRecordsAggregate extends TestCase {
+    public void testCFRecordsAggregate() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet sheet = workbook.createSheet();
 
-        List recs = new ArrayList();
-		CFHeaderRecord header = new CFHeaderRecord();
-		CFRuleRecord rule1 = CFRuleRecord.create(sheet, "7");
-		CFRuleRecord rule2 = CFRuleRecord.create(sheet, ComparisonOperator.BETWEEN, "2", "5");
-		CFRuleRecord rule3 = CFRuleRecord.create(sheet, ComparisonOperator.GE, "100", null);
-		header.setNumberOfConditionalFormats(3);
-		CellRangeAddress[] cellRanges = {
-				new CellRangeAddress(0,1,0,0),
-				new CellRangeAddress(0,1,2,2),
-		};
-		header.setCellRanges(cellRanges);
-		recs.add(header);
-		recs.add(rule1);
-		recs.add(rule2);
-		recs.add(rule3);
-		CFRecordsAggregate record;
-		record = CFRecordsAggregate.createCFAggregate(new RecordStream(recs, 0));
+        List<Record> recs = new ArrayList<Record>();
+        CFHeaderBase header = new CFHeaderRecord();
+        CFRuleBase rule1 = CFRuleRecord.create(sheet, "7");
+        CFRuleBase rule2 = CFRuleRecord.create(sheet, ComparisonOperator.BETWEEN, "2", "5");
+        CFRuleBase rule3 = CFRuleRecord.create(sheet, ComparisonOperator.GE, "100", null);
+        header.setNumberOfConditionalFormats(3);
+        CellRangeAddress[] cellRanges = {
+                new CellRangeAddress(0,1,0,0),
+                new CellRangeAddress(0,1,2,2),
+        };
+        header.setCellRanges(cellRanges);
+        recs.add(header);
+        recs.add(rule1);
+        recs.add(rule2);
+        recs.add(rule3);
+        CFRecordsAggregate record;
+        record = CFRecordsAggregate.createCFAggregate(new RecordStream(recs, 0));
 
-		// Serialize
-		byte [] serializedRecord = new byte[record.getRecordSize()];
-		record.serialize(0, serializedRecord);
-		InputStream in = new ByteArrayInputStream(serializedRecord);
+        // Serialize
+        byte [] serializedRecord = new byte[record.getRecordSize()];
+        record.serialize(0, serializedRecord);
+        InputStream in = new ByteArrayInputStream(serializedRecord);
 
-		//Parse
-		recs = RecordFactory.createRecords(in);
+        //Parse
+        recs = RecordFactory.createRecords(in);
 
-		// Verify
-		assertNotNull(recs);
-		assertEquals(4, recs.size());
+        // Verify
+        assertNotNull(recs);
+        assertEquals(4, recs.size());
 
-		header = (CFHeaderRecord)recs.get(0);
-		rule1 = (CFRuleRecord)recs.get(1);
-		rule2 = (CFRuleRecord)recs.get(2);
-		rule3 = (CFRuleRecord)recs.get(3);
-		cellRanges = header.getCellRanges();
+        header = (CFHeaderRecord)recs.get(0);
+        rule1 = (CFRuleRecord)recs.get(1);
+        rule2 = (CFRuleRecord)recs.get(2);
+        rule3 = (CFRuleRecord)recs.get(3);
+        cellRanges = header.getCellRanges();
 
-		assertEquals(2, cellRanges.length);
-		assertEquals(3, header.getNumberOfConditionalFormats());
+        assertEquals(2, cellRanges.length);
+        assertEquals(3, header.getNumberOfConditionalFormats());
 
-		record = CFRecordsAggregate.createCFAggregate(new RecordStream(recs, 0));
+        record = CFRecordsAggregate.createCFAggregate(new RecordStream(recs, 0));
 
-		record = record.cloneCFAggregate();
+        record = record.cloneCFAggregate();
 
-		assertNotNull(record.getHeader());
-		assertEquals(3,record.getNumberOfRules());
+        assertNotNull(record.getHeader());
+        assertEquals(3,record.getNumberOfRules());
 
-		header = record.getHeader();
-		rule1 = record.getRule(0);
-		rule2 = record.getRule(1);
-		rule3 = record.getRule(2);
-		cellRanges = header.getCellRanges();
+        header = record.getHeader();
+        rule1 = record.getRule(0);
+        rule2 = record.getRule(1);
+        rule3 = record.getRule(2);
+        cellRanges = header.getCellRanges();
 
-		assertEquals(2, cellRanges.length);
-		assertEquals(3, header.getNumberOfConditionalFormats());
-	}
-	
-	/**
-	 * Make sure that the CF Header record is properly updated with the number of rules
-	 */
-	public void testNRules() {
-		HSSFWorkbook workbook = new HSSFWorkbook();
+        assertEquals(2, cellRanges.length);
+        assertEquals(3, header.getNumberOfConditionalFormats());
+    }
+
+    /**
+     * Make sure that the CF Header record is properly updated with the number of rules
+     */
+    public void testNRules() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet sheet = workbook.createSheet();
-		CellRangeAddress[] cellRanges = {
-				new CellRangeAddress(0,1,0,0),
-				new CellRangeAddress(0,1,2,2),
-		};
-		CFRuleRecord[] rules = {
-			CFRuleRecord.create(sheet, "7"),
-			CFRuleRecord.create(sheet, ComparisonOperator.BETWEEN, "2", "5"),
-		};
-		CFRecordsAggregate agg = new CFRecordsAggregate(cellRanges, rules);
-		byte[] serializedRecord = new byte[agg.getRecordSize()];
-		agg.serialize(0, serializedRecord);
-		
-		int nRules = LittleEndian.getUShort(serializedRecord, 4);
-		if (nRules == 0) {
-			throw new AssertionFailedError("Identified bug 45682 b");
-		}
-		assertEquals(rules.length, nRules);
-	}
+        CellRangeAddress[] cellRanges = {
+                new CellRangeAddress(0,1,0,0),
+                new CellRangeAddress(0,1,2,2),
+        };
+        CFRuleRecord[] rules = {
+                CFRuleRecord.create(sheet, "7"),
+                CFRuleRecord.create(sheet, ComparisonOperator.BETWEEN, "2", "5"),
+        };
+        CFRecordsAggregate agg = new CFRecordsAggregate(cellRanges, rules);
+        byte[] serializedRecord = new byte[agg.getRecordSize()];
+        agg.serialize(0, serializedRecord);
+
+        int nRules = LittleEndian.getUShort(serializedRecord, 4);
+        if (nRules == 0) {
+            throw new AssertionFailedError("Identified bug 45682 b");
+        }
+        assertEquals(rules.length, nRules);
+    }
+    
+    public void testCantMixTypes() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        HSSFSheet sheet = workbook.createSheet();
+        CellRangeAddress[] cellRanges = {
+                new CellRangeAddress(0,1,0,0),
+                new CellRangeAddress(0,1,2,2),
+        };
+        CFRuleBase[] rules = {
+                CFRuleRecord.create(sheet, "7"),
+                CFRule12Record.create(sheet, ComparisonOperator.BETWEEN, "2", "5"),
+        };
+        try {
+            new CFRecordsAggregate(cellRanges, rules);
+            fail("Shouldn't be able to mix between types");
+        } catch (IllegalArgumentException e) {}
+        
+        
+        rules = new CFRuleBase[] { CFRuleRecord.create(sheet, "7") };
+        CFRecordsAggregate agg = new CFRecordsAggregate(cellRanges, rules);
+        
+        try {
+            agg.addRule(CFRule12Record.create(sheet, "7"));
+            fail("Shouldn't be able to mix between types");
+        } catch (IllegalArgumentException e) {}
+    }
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java
index 9d9c044..6c8cd01 100644
--- a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java
+++ b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java
@@ -96,9 +96,21 @@
 		}
 
 		public void confirmShort(int expVal) {
-			cmp(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readUShort()));
+			cmp(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readShort()));
 		}
 
+        public void confirmUShort(int expVal) {
+            cmp(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readUShort()));
+        }
+        
+        public short readShort() {
+            return _bds.readShort();
+        }
+
+        public int readUShort() {
+            return _bds.readUShort();
+        }
+
 		public void confirmInt(int expVal) {
 			cmp(HexDump.intToHex(expVal), HexDump.intToHex(_bds.readInt()));
 		}
@@ -106,7 +118,7 @@
 		public void confirmLong(long expVal) {
 			cmp(HexDump.longToHex(expVal), HexDump.longToHex(_bds.readLong()));
 		}
-
+		
 		private void cmp(char[] exp, char[] act) {
 			if (Arrays.equals(exp, act)) {
 				return;
@@ -166,6 +178,15 @@
 		st.rollForward(0x0C04, 0x0FF8);
 		st.confirmLong(0x6AA2D5F6B975D10CL);
 		st.confirmLong(0x34248ADF7ED4F029L);
+		// check for signed/unsigned shorts #58069
+		st.rollForward(0x1008, 0x7213);
+		st.confirmUShort(0xFFFF);
+		st.rollForward(0x7215, 0x1B9AD);
+        st.confirmShort(-1);
+        st.rollForward(0x1B9AF, 0x37D99);
+        assertEquals(0xFFFF, st.readUShort());
+        st.rollForward(0x37D9B, 0x4A6F2);
+        assertEquals(-1, st.readShort());
 		st.assertNoErrors();
 	}
 
@@ -229,7 +250,7 @@
 		st.confirmData("01 C2 4E 55");  // first 4 bytes in next block
 		st.assertNoErrors();
 	}
-    
+
 	private static StreamTester createStreamTester(int mockStreamStartVal, String keyDigestHex, int expectedFirstInt) {
 		return new StreamTester(new MockStream(mockStreamStartVal), keyDigestHex, expectedFirstInt);
 	}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/StreamUtility.java b/src/testcases/org/apache/poi/hssf/usermodel/StreamUtility.java
index b9f39a0..06aa0b8 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/StreamUtility.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/StreamUtility.java
@@ -82,7 +82,7 @@
 	private static int[] diffInternal(InputStream isA, InputStream isB, int[] allowableDifferenceRegions)
 			throws IOException {
 		int offset = 0;
-		List temp = new ArrayList();
+		List<Integer> temp = new ArrayList<Integer>();
 		while (true) {
 			int b = isA.read();
 			int b2 = isB.read();
@@ -114,7 +114,7 @@
 		return false;
 	}
 
-	private static int[] toPrimitiveIntArray(List temp) {
+	private static int[] toPrimitiveIntArray(List<Integer> temp) {
 		int nItems = temp.size();
 		if(nItems < 1) {
 			return null;
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
index 8736478..af6e8bb 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
@@ -32,6 +32,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -58,6 +59,7 @@
 import org.apache.poi.hssf.record.common.UnicodeString;
 import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.formula.ptg.Area3DPtg;
 import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg;
@@ -71,6 +73,7 @@
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.TempFile;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -108,9 +111,12 @@
         File file;
         try {
             file = TempFile.createTempFile(simpleFileName + "#", ".xls");
-            FileOutputStream out = new FileOutputStream(file);
-            wb.write(out);
-            out.close();
+            OutputStream out = new FileOutputStream(file);
+            try {
+            	wb.write(out);
+            } finally {
+            	out.close();
+            }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
@@ -176,7 +182,7 @@
             cell = row.createCell(3);
 
         // Write test
-        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
+        cell.setCellType(Cell.CELL_TYPE_STRING);
         setCellText(cell, "a test");
 
         // change existing numeric cell value
@@ -289,7 +295,7 @@
         HSSFCell d1 = w.getSheetAt(0).getRow(3).getCell(0);
         HSSFCell d2 = w.getSheetAt(0).getRow(3).getCell(1);
 
-        if (false) {
+        /*
             // THAI code page
             System.out.println("a1="+unicodeString(a1));
             System.out.println("a2="+unicodeString(a2));
@@ -302,7 +308,8 @@
             // US+THAI
             System.out.println("d1="+unicodeString(d1));
             System.out.println("d2="+unicodeString(d2));
-        }
+        */
+
         confirmSameCellText(a1, a2);
         confirmSameCellText(b1, b2);
         confirmSameCellText(c1, c2);
@@ -334,7 +341,7 @@
         assertEquals(a.getRichStringCellValue().getString(), b.getRichStringCellValue().getString());
     }
 
-    private static String unicodeString(HSSFCell cell) {
+    /*private static String unicodeString(HSSFCell cell) {
         String ss = cell.getRichStringCellValue().getString();
         char s[] = ss.toCharArray();
         StringBuffer sb = new StringBuffer();
@@ -342,7 +349,7 @@
             sb.append("\\u").append(Integer.toHexString(s[x]));
         }
         return sb.toString();
-    }
+    }*/
 
     /** Error in opening wb*/
     @Test
@@ -457,7 +464,7 @@
             HSSFRow row =  sheet.getRow(i);
             if (row != null) {
                 HSSFCell cell = row .getCell(0);
-                assertEquals(HSSFCell.CELL_TYPE_STRING, cell.getCellType());
+                assertEquals(Cell.CELL_TYPE_STRING, cell.getCellType());
                 count++;
             }
         }
@@ -884,7 +891,7 @@
         List<HSSFObjectData> objects = wb.getAllEmbeddedObjects();
         assertEquals(1, objects.size());
 
-        HSSFObjectData obj = (HSSFObjectData)objects.get(0);
+        HSSFObjectData obj = objects.get(0);
         assertNotNull(obj);
 
         // Peek inside the underlying record
@@ -973,9 +980,10 @@
 
     /**
      * Test that fonts get added properly
+     * @throws IOException 
      */
     @Test
-    public void bug45338() {
+    public void bug45338() throws IOException {
         HSSFWorkbook wb = new HSSFWorkbook();
         assertEquals(4, wb.getNumberOfFonts());
 
@@ -1054,6 +1062,8 @@
                    "Thingy", false, true, (short)2, (byte)2
                )
         );
+        
+        wb.close();
     }
 
     /**
@@ -1145,13 +1155,13 @@
     }
 
     private static void confirmCachedValue(double expectedValue, HSSFCell cell) {
-        assertEquals(HSSFCell.CELL_TYPE_FORMULA, cell.getCellType());
-        assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cell.getCachedFormulaResultType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType());
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCachedFormulaResultType());
         assertEquals(expectedValue, cell.getNumericCellValue(), 0.0);
     }
     private static void confirmCachedValue(String expectedValue, HSSFCell cell) {
-        assertEquals(HSSFCell.CELL_TYPE_FORMULA, cell.getCellType());
-        assertEquals(HSSFCell.CELL_TYPE_STRING, cell.getCachedFormulaResultType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType());
+        assertEquals(Cell.CELL_TYPE_STRING, cell.getCachedFormulaResultType());
         assertEquals(expectedValue, cell.getRichStringCellValue().getString());
     }
 
@@ -1198,9 +1208,10 @@
     /**
      * People are all getting confused about the last
      *  row and cell number
+     * @throws IOException 
      */
     @Test
-    public void bug30635() {
+    public void bug30635() throws IOException {
         HSSFWorkbook wb = new HSSFWorkbook();
         HSSFSheet s = wb.createSheet();
 
@@ -1243,6 +1254,8 @@
         assertEquals(0, r.getFirstCellNum());
         assertEquals(5, r.getLastCellNum()); // last cell # + 1
         assertEquals(3, r.getPhysicalNumberOfCells());
+        
+        wb.close();
     }
 
     /**
@@ -1261,7 +1274,7 @@
         s = wb.getSheet("OneVariable Table Completed");
         r = s.getRow(3);
         c = r.getCell(4);
-        assertEquals(HSSFCell.CELL_TYPE_FORMULA, c.getCellType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, c.getCellType());
 
         // TODO - check the formula once tables and
         //  arrays are properly supported
@@ -1271,7 +1284,7 @@
         s = wb.getSheet("TwoVariable Table Example");
         r = s.getRow(3);
         c = r.getCell(4);
-        assertEquals(HSSFCell.CELL_TYPE_FORMULA, c.getCellType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, c.getCellType());
 
         // TODO - check the formula once tables and
         //  arrays are properly supported
@@ -1324,7 +1337,7 @@
         assertTrue(wb.isSheetVeryHidden(2));
 
         // Change 0 to be very hidden, and re-load
-        wb.setSheetHidden(0, HSSFWorkbook.SHEET_STATE_VERY_HIDDEN);
+        wb.setSheetHidden(0, Workbook.SHEET_STATE_VERY_HIDDEN);
 
         HSSFWorkbook nwb = writeOutAndReadBack(wb);
 
@@ -1565,10 +1578,26 @@
      * (is an excel 95 file though)
      */
     @Test
-    public void bug46904() {
+    public void bug46904() throws Exception {
         try {
-            openSample("46904.xls");
-            fail();
+            OPOIFSFileSystem fs = new OPOIFSFileSystem(
+                    HSSFITestDataProvider.instance.openWorkbookStream("46904.xls"));
+            new HSSFWorkbook(fs.getRoot(), false).close();
+            fail("Should catch exception here");
+        } catch(OldExcelFormatException e) {
+            assertTrue(e.getMessage().startsWith(
+                    "The supplied spreadsheet seems to be Excel"
+            ));
+        }
+        try {
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(
+                    HSSFITestDataProvider.instance.openWorkbookStream("46904.xls"));
+            try {
+                new HSSFWorkbook(fs.getRoot(), false).close();
+            fail("Should catch exception here");
+            } finally {
+                fs.close();
+            }
         } catch(OldExcelFormatException e) {
             assertTrue(e.getMessage().startsWith(
                     "The supplied spreadsheet seems to be Excel"
@@ -1634,11 +1663,11 @@
     public void bug47251() {
         // Firstly, try with one that triggers on InterfaceHdrRecord
         openSample("47251.xls");
-        
+
         // Now with one that triggers on NoteRecord
         openSample("47251_1.xls");
     }
-    
+
     /**
      * Round trip a file with an unusual UnicodeString/ExtRst record parts
      */
@@ -1646,35 +1675,35 @@
     public void bug47847() throws Exception {
        HSSFWorkbook wb = openSample("47847.xls");
        assertEquals(3, wb.getNumberOfSheets());
-       
+
        // Find the SST record
        UnicodeString withExt = wb.getWorkbook().getSSTString(0);
        UnicodeString withoutExt = wb.getWorkbook().getSSTString(31);
-       
+
        assertEquals("O:Alloc:Qty", withExt.getString());
        assertTrue((withExt.getOptionFlags() & 0x0004) == 0x0004);
-       
+
        assertEquals("RT", withoutExt.getString());
        assertTrue((withoutExt.getOptionFlags() & 0x0004) == 0x0000);
-       
+
        // Something about continues...
 
-       
+
        // Write out and re-read
        wb = writeOutAndReadBack(wb);
        assertEquals(3, wb.getNumberOfSheets());
-       
+
        // Check it's the same now
        withExt = wb.getWorkbook().getSSTString(0);
        withoutExt = wb.getWorkbook().getSSTString(31);
-       
+
        assertEquals("O:Alloc:Qty", withExt.getString());
        assertTrue((withExt.getOptionFlags() & 0x0004) == 0x0004);
-       
+
        assertEquals("RT", withoutExt.getString());
        assertTrue((withoutExt.getOptionFlags() & 0x0004) == 0x0000);
     }
-    
+
     /**
      * Problem with cloning a sheet with a chart
      *  contained in it.
@@ -1683,21 +1712,21 @@
     public void bug49096() throws Exception {
        HSSFWorkbook wb = openSample("49096.xls");
        assertEquals(1, wb.getNumberOfSheets());
-       
+
        assertNotNull(wb.getSheetAt(0));
        wb.cloneSheet(0);
        assertEquals(2, wb.getNumberOfSheets());
-       
+
        wb = writeOutAndReadBack(wb);
        assertEquals(2, wb.getNumberOfSheets());
     }
-    
+
     /**
-     * Newly created sheets need to get a 
+     * Newly created sheets need to get a
      *  proper TabID, otherwise print setup
      *  gets confused on them.
      * Also ensure that print setup refs are
-     *  by reference not value 
+     *  by reference not value
      */
     @Test
     public void bug46664() throws Exception {
@@ -1719,9 +1748,9 @@
                0, //start row
                0  //end row
        );
-       
+
        wb = writeOutAndReadBack(wb);
-       
+
        // Ensure the tab index
        TabIdRecord tr = null;
        for(Record r : wb.getWorkbook().getRecords()) {
@@ -1732,108 +1761,106 @@
        assertNotNull(tr);
        assertEquals(1, tr._tabids.length);
        assertEquals(0, tr._tabids[0]);
-       
+
        // Ensure the print setup
        assertEquals("new_sheet!$A$1:$C$1", wb.getPrintArea(0));
        assertEquals("new_sheet!$A$1:$C$1", wb.getName("Print_Area").getRefersToFormula());
-       
+
        // Needs reference not value
        NameRecord nr = wb.getWorkbook().getNameRecord(
              wb.getNameIndex("Print_Area")
-       ); 
+       );
        assertEquals("Print_Area", nr.getNameText());
        assertEquals(1, nr.getNameDefinition().length);
        assertEquals(
-             "new_sheet!$A$1:$C$1", 
+             "new_sheet!$A$1:$C$1",
              ((Area3DPtg)nr.getNameDefinition()[0]).toFormulaString(HSSFEvaluationWorkbook.create(wb))
        );
        assertEquals('R', nr.getNameDefinition()[0].getRVAType());
     }
-    
+
     /**
-     * Problems with formula references to 
+     * Problems with formula references to
      *  sheets via URLs
      */
     @Test
     public void bug45970() throws Exception {
        HSSFWorkbook wb = openSample("FormulaRefs.xls");
        assertEquals(3, wb.getNumberOfSheets());
-       
+
        HSSFSheet s = wb.getSheetAt(0);
        HSSFRow row;
-       
+
        row = s.getRow(0);
        assertEquals(Cell.CELL_TYPE_NUMERIC, row.getCell(1).getCellType());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(1);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("B1", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(2);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("Sheet1!B1", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(3);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("[Formulas2.xls]Sheet1!B2", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(4);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("'[$http://gagravarr.org/FormulaRefs.xls]Sheet1'!B1", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        // Change 4
        row.getCell(1).setCellFormula("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2");
        row.getCell(1).setCellValue(123.0);
-       
+
        // Add 5
        row = s.createRow(5);
        row.createCell(1, Cell.CELL_TYPE_FORMULA);
        row.getCell(1).setCellFormula("'[$http://example.com/FormulaRefs.xls]Sheet1'!B1");
        row.getCell(1).setCellValue(234.0);
-       
-       
+
+
        // Re-test
        wb = writeOutAndReadBack(wb);
        s = wb.getSheetAt(0);
-       
+
        row = s.getRow(0);
        assertEquals(Cell.CELL_TYPE_NUMERIC, row.getCell(1).getCellType());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(),0);
-       
+
        row = s.getRow(1);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("B1", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(2);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("Sheet1!B1", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        row = s.getRow(3);
        assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
        assertEquals("[Formulas2.xls]Sheet1!B2", row.getCell(1).getCellFormula());
        assertEquals(112.0, row.getCell(1).getNumericCellValue(), 0);
-       
+
        // TODO - Fix these so they work...
-       if(1==2) {
-           row = s.getRow(4);
-           assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
-           assertEquals("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2", row.getCell(1).getCellFormula());
-           assertEquals(123.0, row.getCell(1).getNumericCellValue(), 0);
-           
-           row = s.getRow(5);
-           assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
-           assertEquals("'[$http://example.com/FormulaRefs.xls]Sheet1'!B1", row.getCell(1).getCellFormula());
-           assertEquals(234.0, row.getCell(1).getNumericCellValue(), 0);
-       }
+       /*row = s.getRow(4);
+       assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
+       assertEquals("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2", row.getCell(1).getCellFormula());
+       assertEquals(123.0, row.getCell(1).getNumericCellValue(), 0);
+
+       row = s.getRow(5);
+       assertEquals(Cell.CELL_TYPE_FORMULA, row.getCell(1).getCellType());
+       assertEquals("'[$http://example.com/FormulaRefs.xls]Sheet1'!B1", row.getCell(1).getCellFormula());
+       assertEquals(234.0, row.getCell(1).getNumericCellValue(), 0);*/
     }
-    
+
     /**
      * Test for a file with NameRecord with NameCommentRecord comments
      */
@@ -1842,26 +1869,26 @@
       HSSFWorkbook wb = openSample("49185.xls");
       Name name = wb.getName("foobarName");
       assertEquals("This is a comment", name.getComment());
-      
+
       // Rename the name, comment comes with it
       name.setNameName("ChangedName");
       assertEquals("This is a comment", name.getComment());
-      
+
       // Save and re-check
       wb = writeOutAndReadBack(wb);
       name = wb.getName("ChangedName");
       assertEquals("This is a comment", name.getComment());
-      
+
       // Now try to change it
       name.setComment("Changed Comment");
       assertEquals("Changed Comment", name.getComment());
-      
+
       // Save and re-check
       wb = writeOutAndReadBack(wb);
       name = wb.getName("ChangedName");
       assertEquals("Changed Comment", name.getComment());
     }
-    
+
     /**
      * Vertically aligned text
      */
@@ -1872,11 +1899,11 @@
        Row r = s.getRow(0);
        Cell rotated = r.getCell(0);
        Cell normal = r.getCell(1);
-       
+
        // Check the current ones
        assertEquals(0, normal.getCellStyle().getRotation());
        assertEquals(0xff, rotated.getCellStyle().getRotation());
-       
+
        // Add a new style, also rotated
        CellStyle cs = wb.createCellStyle();
        cs.setRotation((short)0xff);
@@ -1884,22 +1911,22 @@
        nc.setCellValue("New Rotated Text");
        nc.setCellStyle(cs);
        assertEquals(0xff, nc.getCellStyle().getRotation());
-       
+
        // Write out and read back
        wb = writeOutAndReadBack(wb);
-       
+
        // Re-check
        s = wb.getSheetAt(0);
        r = s.getRow(0);
        rotated = r.getCell(0);
        normal = r.getCell(1);
        nc = r.getCell(2);
-       
+
        assertEquals(0, normal.getCellStyle().getRotation());
        assertEquals(0xff, rotated.getCellStyle().getRotation());
        assertEquals(0xff, nc.getCellStyle().getRotation());
     }
-    
+
     /**
      * Setting the user style name on custom styles
      */
@@ -1909,26 +1936,26 @@
        HSSFSheet s = wb.createSheet("Test");
        HSSFRow r = s.createRow(0);
        HSSFCell c = r.createCell(0);
-       
+
        HSSFCellStyle cs1 = wb.createCellStyle();
        HSSFCellStyle cs2 = wb.createCellStyle();
        HSSFCellStyle cs3 = wb.createCellStyle();
-       
+
        assertEquals(21, cs1.getIndex());
        cs1.setUserStyleName("Testing");
-       
+
        assertEquals(22, cs2.getIndex());
        cs2.setUserStyleName("Testing 2");
-       
+
        assertEquals(23, cs3.getIndex());
        cs3.setUserStyleName("Testing 3");
-       
+
        // Set one
        c.setCellStyle(cs1);
-       
+
        // Write out and read back
        wb = writeOutAndReadBack(wb);
-       
+
        // Re-check
        assertEquals("Testing", wb.getCellStyleAt((short)21).getUserStyleName());
        assertEquals("Testing 2", wb.getCellStyleAt((short)22).getUserStyleName());
@@ -1941,7 +1968,7 @@
         short numCellStyles = wb.getNumCellStyles();
         List<String> namedStyles = Arrays.asList(
                 "20% - Accent1", "20% - Accent2", "20% - Accent3", "20% - Accent4", "20% - Accent5",
-                "20% - Accent6", "40% - Accent1", "40% - Accent2", "40% - Accent3", "40% - Accent4", 
+                "20% - Accent6", "40% - Accent1", "40% - Accent2", "40% - Accent3", "40% - Accent4",
                 "40% - Accent5", "40% - Accent6", "60% - Accent1", "60% - Accent2", "60% - Accent3",
                 "60% - Accent4", "60% - Accent5", "60% - Accent6", "Accent1", "Accent2", "Accent3",
                 "Accent4", "Accent5", "Accent6", "Bad", "Calculation", "Check Cell", "Explanatory Text",
@@ -1957,19 +1984,19 @@
             }
         }
         assertTrue(namedStyles.containsAll(collecteddStyles));
-    }    
-    
+    }
+
     /**
      * Regression with the PageSettingsBlock
      */
     @Test
     public void bug49931() throws Exception {
        HSSFWorkbook wb = openSample("49931.xls");
-       
+
        assertEquals(1, wb.getNumberOfSheets());
        assertEquals("Foo", wb.getSheetAt(0).getRow(0).getCell(0).getRichStringCellValue().toString());
     }
-    
+
     /**
      * Missing left/right/centre options on a footer
      */
@@ -1984,7 +2011,7 @@
        assertEquals("Left text should be empty", "", f.getLeft());
        assertEquals("Right text should be empty", "", f.getRight());
        assertEquals(
-             "Center text should contain the illegal value", 
+             "Center text should contain the illegal value",
              "BlahBlah blah blah  ", f.getCenter()
        );
     }
@@ -2003,12 +2030,13 @@
        HSSFWorkbook wb = openSample("50426.xls");
        writeOutAndReadBack(wb);
     }
-    
+
     /**
      * Last row number when shifting rows
+     * @throws IOException 
      */
     @Test
-    public void bug50416LastRowNumber() {
+    public void bug50416LastRowNumber() throws IOException {
        // Create the workbook with 1 sheet which contains 3 rows
        HSSFWorkbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet("Bug50416");
@@ -2021,10 +2049,10 @@
        Row row3 = sheet.createRow(2);
        Cell cellA_3 = row3.createCell(0,Cell.CELL_TYPE_STRING);
        cellA_3.setCellValue("Cell A,3");
-       
+
        // Test the last Row number it currently correct
        assertEquals(2, sheet.getLastRowNum());
-       
+
        // Shift the first row to the end
        sheet.shiftRows(0, 0, 3);
        assertEquals(3, sheet.getLastRowNum());
@@ -2032,7 +2060,7 @@
        assertEquals("Cell A,2", sheet.getRow(1).getCell(0).getStringCellValue());
        assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue());
        assertEquals("Cell A,1", sheet.getRow(3).getCell(0).getStringCellValue());
-       
+
        // Shift the 2nd row up to the first one
        sheet.shiftRows(1, 1, -1);
        assertEquals(3, sheet.getLastRowNum());
@@ -2048,17 +2076,19 @@
        assertEquals("Cell A,1", sheet.getRow(1).getCell(0).getStringCellValue());
        assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue());
        assertEquals(-1,         sheet.getRow(3).getLastCellNum());
-       
+
        // Now zap the empty 4th row - won't do anything
        sheet.removeRow(sheet.getRow(3));
-       
+
        // Test again the last row number which should be 2
        assertEquals(2, sheet.getLastRowNum());
        assertEquals("Cell A,2", sheet.getRow(0).getCell(0).getStringCellValue());
        assertEquals("Cell A,1", sheet.getRow(1).getCell(0).getStringCellValue());
        assertEquals("Cell A,3", sheet.getRow(2).getCell(0).getStringCellValue());
+       
+       workbook.close();
     }
-    
+
     /**
      * If you send a file between Excel and OpenOffice enough, something
      *  will turn the "General" format into "GENERAL"
@@ -2070,7 +2100,7 @@
        HSSFRow r17 = s.getRow(16);
        HSSFRow r18 = s.getRow(17);
        HSSFDataFormatter df = new HSSFDataFormatter();
-       
+
        assertEquals(10.0, r17.getCell(1).getNumericCellValue(), 0);
        assertEquals(20.0, r17.getCell(2).getNumericCellValue(), 0);
        assertEquals(20.0, r17.getCell(3).getNumericCellValue(), 0);
@@ -2080,7 +2110,7 @@
        assertEquals("10", df.formatCellValue(r17.getCell(1)));
        assertEquals("20", df.formatCellValue(r17.getCell(2)));
        assertEquals("20", df.formatCellValue(r17.getCell(3)));
-       
+
        assertEquals(16.0, r18.getCell(1).getNumericCellValue(), 0);
        assertEquals(35.0, r18.getCell(2).getNumericCellValue(), 0);
        assertEquals(123.0, r18.getCell(3).getNumericCellValue(), 0);
@@ -2091,7 +2121,7 @@
        assertEquals("35", df.formatCellValue(r18.getCell(2)));
        assertEquals("123", df.formatCellValue(r18.getCell(3)));
     }
-    
+
     /**
      * A protected sheet with comments, when written out by
      *  POI, ends up upsetting excel.
@@ -2100,32 +2130,32 @@
      */
     @Test
     public void bug50833() throws Exception {
-       Biff8EncryptionKey.setCurrentUserPassword(null); 
-        
+       Biff8EncryptionKey.setCurrentUserPassword(null);
+
        HSSFWorkbook wb = openSample("50833.xls");
        HSSFSheet s = wb.getSheetAt(0);
        assertEquals("Sheet1", s.getSheetName());
        assertEquals(false, s.getProtect());
-       
+
        HSSFCell c = s.getRow(0).getCell(0);
        assertEquals("test cell value", c.getRichStringCellValue().getString());
-       
+
        HSSFComment cmt = c.getCellComment();
        assertNotNull(cmt);
        assertEquals("Robert Lawrence", cmt.getAuthor());
        assertEquals("Robert Lawrence:\ntest comment", cmt.getString().getString());
-       
+
        // Reload
        wb = writeOutAndReadBack(wb);
        s = wb.getSheetAt(0);
        c = s.getRow(0).getCell(0);
-       
+
        // Re-check the comment
        cmt = c.getCellComment();
        assertNotNull(cmt);
        assertEquals("Robert Lawrence", cmt.getAuthor());
        assertEquals("Robert Lawrence:\ntest comment", cmt.getString().getString());
-       
+
        // TODO Identify what excel doesn't like, and check for that
     }
 
@@ -2140,26 +2170,26 @@
 
     /**
      * The spec says that ChartEndObjectRecord has 6 reserved
-     *  bytes on the end, but we sometimes find files without... 
+     *  bytes on the end, but we sometimes find files without...
      */
     @Test
     public void bug50939() throws Exception {
        HSSFWorkbook wb = openSample("50939.xls");
        assertEquals(2, wb.getNumberOfSheets());
     }
-    
+
     @Test
     public void bug49219() throws Exception {
        HSSFWorkbook wb = openSample("49219.xls");
        assertEquals(1, wb.getNumberOfSheets());
        assertEquals("DGATE", wb.getSheetAt(0).getRow(1).getCell(0).getStringCellValue());
     }
-    
+
     @Test
     public void bug48968() throws Exception {
        HSSFWorkbook wb = openSample("48968.xls");
        assertEquals(1, wb.getNumberOfSheets());
-       
+
        DataFormatter fmt = new DataFormatter();
 
        // Check the dates
@@ -2172,7 +2202,7 @@
        // There is no such thing as 00/01/1900...
        assertEquals("00/01/1900 06:14:24", s.getRow(21).getCell(3).getStringCellValue());
        assertEquals("31/12/1899 06:14:24", fmt.formatCellValue(cell_d19000100));
-       
+
        // Check the cached values
        assertEquals("HOUR(A1)",   s.getRow(5).getCell(0).getCellFormula());
        assertEquals(11.0,         s.getRow(5).getCell(0).getNumericCellValue(), 0);
@@ -2180,7 +2210,7 @@
        assertEquals(39.0,         s.getRow(6).getCell(0).getNumericCellValue(), 0);
        assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
        assertEquals(54.0,         s.getRow(7).getCell(0).getNumericCellValue(), 0);
-       
+
        // Re-evaulate and check
        HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
        assertEquals("HOUR(A1)",   s.getRow(5).getCell(0).getCellFormula());
@@ -2189,11 +2219,11 @@
        assertEquals(39.0,         s.getRow(6).getCell(0).getNumericCellValue(), 0);
        assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
        assertEquals(54.0,         s.getRow(7).getCell(0).getNumericCellValue(), 0);
-       
+
        // Push the time forward a bit and check
        double date = s.getRow(0).getCell(0).getNumericCellValue();
        s.getRow(0).getCell(0).setCellValue(date + 1.26);
-       
+
        HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
        assertEquals("HOUR(A1)",   s.getRow(5).getCell(0).getCellFormula());
        assertEquals(11.0+6.0,     s.getRow(5).getCell(0).getNumericCellValue(), 0);
@@ -2202,9 +2232,9 @@
        assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
        assertEquals(54.0+24.0-60, s.getRow(7).getCell(0).getNumericCellValue(), 0);
     }
-    
+
     /**
-     * Mixture of Ascii and Unicode strings in a 
+     * Mixture of Ascii and Unicode strings in a
      *  NameComment record
      */
     @Test
@@ -2214,25 +2244,25 @@
        wb = writeOutAndReadBack(wb);
        assertEquals(1, wb.getNumberOfSheets());
     }
-    
+
     /**
      * File with exactly 256 data blocks (+header block)
-     *  shouldn't break on POIFS loading 
+     *  shouldn't break on POIFS loading
      */
     @SuppressWarnings("resource")
     @Test
     public void bug51461() throws Exception {
        byte[] data = HSSFITestDataProvider.instance.getTestDataFileContent("51461.xls");
-       
+
        HSSFWorkbook wbPOIFS = new HSSFWorkbook(new POIFSFileSystem(
              new ByteArrayInputStream(data)).getRoot(), false);
        HSSFWorkbook wbNPOIFS = new HSSFWorkbook(new NPOIFSFileSystem(
              new ByteArrayInputStream(data)).getRoot(), false);
-       
+
        assertEquals(2, wbPOIFS.getNumberOfSheets());
        assertEquals(2, wbNPOIFS.getNumberOfSheets());
     }
-    
+
     /**
      * Large row numbers and NPOIFS vs POIFS
      */
@@ -2240,22 +2270,22 @@
     @Test
     public void bug51535() throws Exception {
        byte[] data = HSSFITestDataProvider.instance.getTestDataFileContent("51535.xls");
-       
+
        HSSFWorkbook wbPOIFS = new HSSFWorkbook(new POIFSFileSystem(
              new ByteArrayInputStream(data)).getRoot(), false);
        HSSFWorkbook wbNPOIFS = new HSSFWorkbook(new NPOIFSFileSystem(
              new ByteArrayInputStream(data)).getRoot(), false);
-       
+
        for(HSSFWorkbook wb : new HSSFWorkbook[] {wbPOIFS, wbNPOIFS}) {
           assertEquals(3, wb.getNumberOfSheets());
-          
+
           // Check directly
           HSSFSheet s = wb.getSheetAt(0);
           assertEquals("Top Left Cell", s.getRow(0).getCell(0).getStringCellValue());
           assertEquals("Top Right Cell", s.getRow(0).getCell(255).getStringCellValue());
           assertEquals("Bottom Left Cell", s.getRow(65535).getCell(0).getStringCellValue());
           assertEquals("Bottom Right Cell", s.getRow(65535).getCell(255).getStringCellValue());
-          
+
           // Extract and check
           ExcelExtractor ex = new ExcelExtractor(wb);
           String text = ex.getText();
@@ -2272,7 +2302,7 @@
         HSSFWorkbook wb = openSample("51670.xls");
         writeOutAndReadBack(wb);
     }
-    
+
     /**
      * Sum across multiple workbooks
      *  eg =SUM($Sheet2.A1:$Sheet3.A1)
@@ -2282,15 +2312,15 @@
     public void test48703() {
         HSSFWorkbook wb = openSample("48703.xls");
         assertEquals(3, wb.getNumberOfSheets());
-        
+
         // Check reading the formula
         Sheet sheet = wb.getSheetAt(0);
         Row r = sheet.getRow(0);
         Cell c = r.getCell(0);
-        
+
         assertEquals("SUM(Sheet2!A1:Sheet3!A1)", c.getCellFormula());
         assertEquals(4.0, c.getNumericCellValue(), 0);
-        
+
         // Check the evaluated result
         HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(wb);
         eval.evaluateFormulaCell(c);
@@ -2328,7 +2358,7 @@
         // make sure we are still readable
         writeOutAndReadBack(workbook);
     }
-    
+
     /**
      * Note - part of this test is still failing, see
      * {@link TestUnfixedBugs#test49612()}
@@ -2353,7 +2383,7 @@
         assertEquals("evaluating d1", 30.0, eval.evaluate(d1).getNumberValue(), 0.001);
         assertEquals("evaluating e1", 30.0, eval.evaluate(e1).getNumberValue(), 0.001);
     }
-    
+
     @Test
     public void bug51675(){
         final List<Short> list = new ArrayList<Short>();
@@ -2362,6 +2392,7 @@
         InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
         PageSettingsBlock psb = (PageSettingsBlock) ish.getRecords().get(13);
         psb.visitContainedRecords(new RecordAggregate.RecordVisitor() {
+            @Override
             public void visitRecord(Record r) {
                 list.add(r.getSid());
             }
@@ -2369,27 +2400,32 @@
         assertTrue(list.get(list.size()-1).intValue() == UnknownRecord.BITMAP_00E9);
         assertTrue(list.get(list.size()-2).intValue() == UnknownRecord.HEADER_FOOTER_089C);
     }
-    
+
     @Test
-    public void bug52272(){
+    public void bug52272() throws IOException{
         HSSFWorkbook wb = new HSSFWorkbook();
         HSSFSheet sh = wb.createSheet();
         HSSFPatriarch p = sh.createDrawingPatriarch();
-        
+
         HSSFSimpleShape s = p.createSimpleShape(new HSSFClientAnchor());
         s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
 
         HSSFSheet sh2 = wb.cloneSheet(0);
         assertNotNull(sh2.getDrawingPatriarch());
+        
+        wb.close();
     }
 
     @Test
-    public void bug53432(){
+    public void bug53432() throws IOException{
         Workbook wb = new HSSFWorkbook(); //or new HSSFWorkbook();
         wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
         assertEquals(wb.getAllPictures().size(), 1);
+        wb.close();
 
+        wb.close();
         wb = new HSSFWorkbook();
+
         wb = writeOutAndReadBack((HSSFWorkbook) wb);
         assertEquals(wb.getAllPictures().size(), 0);
         wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
@@ -2397,6 +2433,8 @@
 
         wb = writeOutAndReadBack((HSSFWorkbook) wb);
         assertEquals(wb.getAllPictures().size(), 1);
+        
+        wb.close();
     }
 
     @Test
@@ -2448,7 +2486,7 @@
         HSSFSheet sheet = wb.getSheetAt(0);
         HSSFRow row = sheet.getRow(0);
         HSSFCellStyle rstyle = row.getRowStyle();
-        assertEquals(rstyle.getBorderBottom(), HSSFCellStyle.BORDER_DOUBLE);
+        assertEquals(rstyle.getBorderBottom(), CellStyle.BORDER_DOUBLE);
     }
 
     @Test
@@ -2460,7 +2498,7 @@
         } finally {
             Biff8EncryptionKey.setCurrentUserPassword(null);
         }
-        
+
         // One using the only-recently-documented encryption header type 4,
         //  and the RC4 CryptoAPI encryption header structure
         try {
@@ -2484,7 +2522,7 @@
         }
         assertEquals(0, comments);
     }
-    
+
     /**
      * Files initially created with Excel 2010 can have >3 CF rules
      */
@@ -2492,10 +2530,10 @@
     public void bug56482() {
         HSSFWorkbook wb = openSample("56482.xls");
         assertEquals(1, wb.getNumberOfSheets());
-        
+
         HSSFSheet sheet = wb.getSheetAt(0);
         HSSFSheetConditionalFormatting cf = sheet.getSheetConditionalFormatting();
-        
+
         assertEquals(5, cf.getNumConditionalFormattings());
     }
 
@@ -2507,11 +2545,11 @@
         InputStream stream = new FileInputStream(file);
         try {
             POIFSFileSystem fs = new POIFSFileSystem(stream);
-            wb = new HSSFWorkbook(fs);            
+            wb = new HSSFWorkbook(fs);
         } finally {
             stream.close();
         }
-        
+
         assertEquals(3, wb.getNumberOfSheets());
         wb.removeSheetAt(0);
         assertEquals(2, wb.getNumberOfSheets());
@@ -2522,55 +2560,82 @@
         assertEquals(1, wb.getNumberOfSheets());
         wb.removeSheetAt(0);
         assertEquals(0, wb.getNumberOfSheets());
-        
+
         wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
         assertEquals(0, wb.getNumberOfSheets());
     }
-    
+
+    @Test
+    public void bug56325a() throws IOException {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("56325a.xls");
+
+        HSSFSheet sheet = wb.cloneSheet(2);
+        wb.setSheetName(3, "Clone 1");
+        sheet.setRepeatingRows(CellRangeAddress.valueOf("2:3"));
+        wb.setPrintArea(3, "$A$4:$C$10");
+
+        sheet = wb.cloneSheet(2);
+        wb.setSheetName(4, "Clone 2");
+        sheet.setRepeatingRows(CellRangeAddress.valueOf("2:3"));
+        wb.setPrintArea(4, "$A$4:$C$10");
+
+        wb.removeSheetAt(2);
+
+        Workbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertEquals(4, wbBack.getNumberOfSheets());
+        
+//        OutputStream fOut = new FileOutputStream("C:\\temp\\56325a.xls");
+//        try {
+//        	wb.write(fOut);
+//        } finally {
+//        	fOut.close();
+//        }
+    }
+
     /**
      * Formulas which reference named ranges, either in other
      *  sheets, or workbook scoped but in other workbooks.
-     * Used to fail with 
+     * Used to fail with
      * java.lang.RuntimeException: Unexpected eval class (org.apache.poi.ss.formula.eval.NameXEval)
      */
     @Test
     public void bug56737() throws IOException {
         Workbook wb = openSample("56737.xls");
-        
+
         // Check the named range definitions
         Name nSheetScope = wb.getName("NR_To_A1");
         Name nWBScope = wb.getName("NR_Global_B2");
 
         assertNotNull(nSheetScope);
         assertNotNull(nWBScope);
-        
+
         assertEquals("Defines!$A$1", nSheetScope.getRefersToFormula());
         assertEquals("Defines!$B$2", nWBScope.getRefersToFormula());
-        
+
         // Check the different kinds of formulas
         Sheet s = wb.getSheetAt(0);
         Cell cRefSName = s.getRow(1).getCell(3);
         Cell cRefWName = s.getRow(2).getCell(3);
-        
+
         assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula());
-        
+
         // TODO Correct this, so that the filename is shown too, see bug #56742
         // This is what Excel itself shows
         //assertEquals("'56737.xls'!NR_Global_B2", cRefWName.getCellFormula());
         // TODO This isn't right, but it's what we currently generate....
         assertEquals("NR_Global_B2", cRefWName.getCellFormula());
-        
+
         // Try to evaluate them
         FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
         assertEquals("Test A1", eval.evaluate(cRefSName).getStringValue());
         assertEquals(142, (int)eval.evaluate(cRefWName).getNumberValue());
-        
+
         // Try to evaluate everything
         eval.evaluateAll();
     }
-    
+
     /**
-     * ClassCastException in HSSFOptimiser - StyleRecord cannot be cast to 
+     * ClassCastException in HSSFOptimiser - StyleRecord cannot be cast to
      * ExtendedFormatRecord when removing un-used styles
      */
     @Test
@@ -2578,20 +2643,20 @@
         HSSFWorkbook workbook = new HSSFWorkbook( );
         HSSFCellStyle style = workbook.createCellStyle();
         HSSFCellStyle newStyle = workbook.createCellStyle();
-                    
+
         HSSFSheet mySheet = workbook.createSheet();
         HSSFRow row = mySheet.createRow(0);
         HSSFCell cell = row.createCell(0);
-        
+
         // Use style
         cell.setCellStyle(style);
         // Switch to newStyle, style is now un-used
         cell.setCellStyle(newStyle);
-        
+
         // Optimise
         HSSFOptimiser.optimiseCellStyles(workbook);
     }
-    
+
     /**
      * Intersection formula ranges, eg =(C2:D3 D3:E4)
      */
@@ -2604,9 +2669,9 @@
         Cell intF = s.getRow(2).getCell(0);
         assertEquals(Cell.CELL_TYPE_FORMULA, intF.getCellType());
         assertEquals(Cell.CELL_TYPE_NUMERIC, intF.getCachedFormulaResultType());
-        
+
         assertEquals("(C2:D3 D3:E4)", intF.getCellFormula());
-        
+
         // Check we can evaluate it correctly
         FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
         assertEquals("4.0", eval.evaluate(intF).formatAsString());
@@ -2618,7 +2683,7 @@
         Sheet s = wb.getSheetAt(0);
         for(int row = 0;row < 7;row++) {
             assertEquals("A$1+B$1", s.getRow(row).getCell(2).getCellFormula());
-        }        
+        }
     }
 
     /**
@@ -2631,7 +2696,7 @@
         assertEquals("International Communication Services SA", s.getRow(2).getCell(0).getStringCellValue());
         assertEquals("Saudi Arabia-Riyadh", s.getRow(210).getCell(0).getStringCellValue());
     }
-    
+
     /**
      * Read, write, read for formulas point to cells in other files.
      * See {@link #bug46670()} for the main test, this just
@@ -2644,20 +2709,20 @@
         HSSFWorkbook wb;
         Sheet s;
         Cell c;
-        
+
         // Expected values
         String refLocal = "'[refs/airport.xls]Sheet1'!$A$2";
         String refHttp  = "'[9http://www.principlesofeconometrics.com/excel/airline.xls]Sheet1'!$A$2";
-        
+
         // Check we can read them correctly
         wb = openSample("46670_local.xls");
         s = wb.getSheetAt(0);
         assertEquals(refLocal, s.getRow(0).getCell(0).getCellFormula());
-        
+
         wb = openSample("46670_http.xls");
         s = wb.getSheetAt(0);
         assertEquals(refHttp, s.getRow(0).getCell(0).getCellFormula());
-        
+
         // Now try to set them to the same values, and ensure that
         //  they end up as they did before, even with a save and re-load
         wb = openSample("46670_local.xls");
@@ -2665,18 +2730,18 @@
         c = s.getRow(0).getCell(0);
         c.setCellFormula(refLocal);
         assertEquals(refLocal, c.getCellFormula());
-        
+
         wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
         s = wb.getSheetAt(0);
         assertEquals(refLocal, s.getRow(0).getCell(0).getCellFormula());
 
-        
+
         wb = openSample("46670_http.xls");
         s = wb.getSheetAt(0);
         c = s.getRow(0).getCell(0);
         c.setCellFormula(refHttp);
         assertEquals(refHttp, c.getCellFormula());
-        
+
         wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
         s = wb.getSheetAt(0);
         assertEquals(refHttp, s.getRow(0).getCell(0).getCellFormula());
@@ -2687,4 +2752,69 @@
         Workbook wb = openSample("57456.xls");
         wb.close();
     }
+
+    @Test
+    public void test57163() throws IOException {
+        Workbook wb = openSample("57163.xls");
+
+        while (wb.getNumberOfSheets() > 1) {
+            wb.removeSheetAt(1);
+        }
+        wb.close();
+    }
+
+    @Test
+    public void test53109() throws IOException {
+        HSSFWorkbook wb = openSample("53109.xls");
+        
+        Workbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertNotNull(wbBack);
+        
+        wb.close();
+    }
+    
+    @Test
+    public void test53109a() throws IOException {
+        HSSFWorkbook wb = openSample("com.aida-tour.www_SPO_files_maldives%20august%20october.xls");
+        
+        Workbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertNotNull(wbBack);
+        
+        wb.close();
+    }
+    
+    @Test
+    public void test48043() throws IOException {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("56325a.xls");
+        
+        wb.removeSheetAt(2);
+        wb.removeSheetAt(1);
+        
+        //Sheet s = wb.createSheet("sheetname");
+        Sheet s = wb.getSheetAt(0);
+        Row row = s.createRow(0);
+        Cell cell = row.createCell(0);
+
+        cell.setCellFormula(
+                "IF(AND(ISBLANK(A10)," +
+                "ISBLANK(B10)),\"\"," + 
+                "CONCATENATE(A10,\"-\",B10))");
+        
+        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
+        
+        eval.evaluateAll();
+        
+        /*OutputStream out = new FileOutputStream("C:\\temp\\48043.xls");
+        try {
+          wb.write(out);
+        } finally {
+          out.close();
+        }*/
+        
+        Workbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertNotNull(wbBack);
+        wbBack.close();
+
+        wb.close();
+    }
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java
index 56a5bb1..6813baa 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java
@@ -26,6 +26,7 @@
 
 import org.apache.poi.ddf.EscherDgRecord;
 import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
 import org.apache.poi.hssf.record.EscherAggregate;
 import org.apache.poi.ss.util.CellRangeAddress;
 
@@ -37,19 +38,22 @@
  */
 public final class TestCloneSheet extends TestCase {
 
-	public void testCloneSheetBasic(){
+	public void testCloneSheetBasic() throws IOException{
 		HSSFWorkbook b = new HSSFWorkbook();
 		HSSFSheet s = b.createSheet("Test");
 		s.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
 		HSSFSheet clonedSheet = b.cloneSheet(0);
 
 		assertEquals("One merged area", 1, clonedSheet.getNumMergedRegions());
+		
+		b.close();
 	}
 
 	/**
 	 * Ensures that pagebreak cloning works properly
+	 * @throws IOException 
 	 */
-	public void testPageBreakClones() {
+	public void testPageBreakClones() throws IOException {
 		HSSFWorkbook b = new HSSFWorkbook();
 		HSSFSheet s = b.createSheet("Test");
 		s.setRowBreak(3);
@@ -62,6 +66,8 @@
 		s.removeRowBreak(3);
 
 		assertTrue("Row 3 still should be broken", clone.isRowBroken(3));
+		
+		b.close();
 	}
     
     public void testCloneSheetWithoutDrawings(){
@@ -121,16 +127,32 @@
         HSSFSheet sh2 = wb.cloneSheet(0);
         HSSFPatriarch p2 = sh2.getDrawingPatriarch();
         HSSFComment c2 = (HSSFComment) p2.getChildren().get(0);
+
+        assertEquals(c.getString(), c2.getString());
+        assertEquals(c.getRow(), c2.getRow());
+        assertEquals(c.getColumn(), c2.getColumn());
+
+        // The ShapeId is not equal? 
+        // assertEquals(c.getNoteRecord().getShapeId(), c2.getNoteRecord().getShapeId());
         
         assertArrayEquals(c2.getTextObjectRecord().serialize(), c.getTextObjectRecord().serialize());
-        assertArrayEquals(c2.getObjRecord().serialize(), c.getObjRecord().serialize());
-        assertArrayEquals(c2.getNoteRecord().serialize(), c.getNoteRecord().serialize());
+        
+        // ShapeId is different
+        CommonObjectDataSubRecord subRecord = (CommonObjectDataSubRecord) c2.getObjRecord().getSubRecords().get(0);
+        subRecord.setObjectId(1025);
 
+        assertArrayEquals(c2.getObjRecord().serialize(), c.getObjRecord().serialize());
+
+        // ShapeId is different
+        c2.getNoteRecord().setShapeId(1025);
+        assertArrayEquals(c2.getNoteRecord().serialize(), c.getNoteRecord().serialize());
 
         //everything except spRecord.shapeId must be the same
         assertFalse(Arrays.equals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize()));
         EscherSpRecord sp = (EscherSpRecord) c2.getEscherContainer().getChild(0);
         sp.setShapeId(1025);
         assertArrayEquals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize());
+        
+        wb.close();
     }
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestComment.java b/src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
index cac444b..2613e8c 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
@@ -17,23 +17,30 @@
 

 package org.apache.poi.hssf.usermodel;

 

+import static org.junit.Assert.assertArrayEquals;

+

+import java.io.IOException;

+

 import junit.framework.TestCase;

+

 import org.apache.poi.ddf.EscherSpRecord;

 import org.apache.poi.hssf.HSSFTestDataSamples;

 import org.apache.poi.hssf.model.CommentShape;

 import org.apache.poi.hssf.model.HSSFTestModelHelper;

-import org.apache.poi.hssf.record.*;

-

-import java.io.*;

-import java.util.Arrays;

+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;

+import org.apache.poi.hssf.record.EscherAggregate;

+import org.apache.poi.hssf.record.NoteRecord;

+import org.apache.poi.hssf.record.ObjRecord;

+import org.apache.poi.hssf.record.TextObjectRecord;

 

 /**

  * @author Evgeniy Berlog

  * @date 26.06.12

  */

+@SuppressWarnings("deprecation")

 public class TestComment extends TestCase {

 

-    public void testResultEqualsToAbstractShape() {

+	public void testResultEqualsToAbstractShape() throws IOException {

         HSSFWorkbook wb = new HSSFWorkbook();

         HSSFSheet sh = wb.createSheet();

         HSSFPatriarch patriarch = sh.createDrawingPatriarch();

@@ -53,34 +60,35 @@
         byte[] actual = comment.getEscherContainer().getChild(0).serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

 

         expected = commentShape.getSpContainer().getChild(2).serialize();

         actual = comment.getEscherContainer().getChild(2).serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

 

         expected = commentShape.getSpContainer().getChild(3).serialize();

         actual = comment.getEscherContainer().getChild(3).serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

 

         expected = commentShape.getSpContainer().getChild(4).serialize();

         actual = comment.getEscherContainer().getChild(4).serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

 

         ObjRecord obj = comment.getObjRecord();

         ObjRecord objShape = commentShape.getObjRecord();

-        /**shapeId = 1025 % 1024**/

-        ((CommonObjectDataSubRecord)objShape.getSubRecords().get(0)).setObjectId(1);

 

         expected = obj.serialize();

         actual = objShape.serialize();

 

+        assertEquals(expected.length, actual.length);

+        //assertArrayEquals(expected, actual);

+

         TextObjectRecord tor = comment.getTextObjectRecord();

         TextObjectRecord torShape = commentShape.getTextObjectRecord();

 

@@ -88,20 +96,21 @@
         actual = torShape.serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

 

         NoteRecord note = comment.getNoteRecord();

         NoteRecord noteShape = commentShape.getNoteRecord();

-        noteShape.setShapeId(1);

 

         expected = note.serialize();

         actual = noteShape.serialize();

 

         assertEquals(expected.length, actual.length);

-        assertTrue(Arrays.equals(expected, actual));

+        assertArrayEquals(expected, actual);

+

+        wb.close();

     }

 

-    public void testAddToExistingFile() {

+    public void testAddToExistingFile() throws IOException {

         HSSFWorkbook wb = new HSSFWorkbook();

         HSSFSheet sh = wb.createSheet();

         HSSFPatriarch patriarch = sh.createDrawingPatriarch();

@@ -118,8 +127,8 @@
 

         assertEquals(patriarch.getChildren().size(), 2);

 

-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);

-        sh = wb.getSheetAt(0);

+        HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);

+        sh = wbBack.getSheetAt(0);

         patriarch = sh.getDrawingPatriarch();

 

         comment = (HSSFComment) patriarch.getChildren().get(1);

@@ -132,8 +141,8 @@
         comment.setString(new HSSFRichTextString("comment3"));

 

         assertEquals(patriarch.getChildren().size(), 3);

-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);

-        sh = wb.getSheetAt(0);

+        HSSFWorkbook wbBack2 = HSSFTestDataSamples.writeOutAndReadBack(wbBack);

+        sh = wbBack2.getSheetAt(0);

         patriarch = sh.getDrawingPatriarch();

         comment = (HSSFComment) patriarch.getChildren().get(1);

         assertEquals(comment.getBackgroundImageId(), 0);

@@ -141,6 +150,10 @@
         assertEquals(((HSSFComment) patriarch.getChildren().get(0)).getString().getString(), "comment1");

         assertEquals(((HSSFComment) patriarch.getChildren().get(1)).getString().getString(), "comment2");

         assertEquals(((HSSFComment) patriarch.getChildren().get(2)).getString().getString(), "comment3");

+        

+        wb.close();

+        wbBack.close();

+        wbBack2.close();

     }

 

     public void testSetGetProperties() throws IOException {

@@ -164,8 +177,8 @@
         comment.setVisible(false);

         assertEquals(comment.isVisible(), false);

 

-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);

-        sh = wb.getSheetAt(0);

+        HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);

+        sh = wbBack.getSheetAt(0);

         patriarch = sh.getDrawingPatriarch();

 

         comment = (HSSFComment) patriarch.getChildren().get(0);

@@ -182,8 +195,8 @@
         comment.setRow(42);

         comment.setVisible(true);

 

-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);

-        sh = wb.getSheetAt(0);

+        HSSFWorkbook wbBack2 = HSSFTestDataSamples.writeOutAndReadBack(wbBack);

+        sh = wbBack2.getSheetAt(0);

         patriarch = sh.getDrawingPatriarch();

         comment = (HSSFComment) patriarch.getChildren().get(0);

 

@@ -192,6 +205,10 @@
         assertEquals(comment.getColumn(), 32);

         assertEquals(comment.getRow(), 42);

         assertEquals(comment.isVisible(), true);

+        

+        wb.close();

+        wbBack.close();

+        wbBack2.close();

     }

 

     public void testExistingFileWithComment(){

@@ -206,7 +223,7 @@
         assertEquals(comment.getRow(), 2);

     }

 

-    public void testFindComments(){

+    public void testFindComments() throws IOException{

         HSSFWorkbook wb = new HSSFWorkbook();

         HSSFSheet sh = wb.createSheet();

         HSSFPatriarch patriarch = sh.createDrawingPatriarch();

@@ -221,14 +238,17 @@
         assertNotNull(sh.findCellComment(5, 4));

         assertNull(sh.findCellComment(5, 5));

 

-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);

-        sh = wb.getSheetAt(0);

+        HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);

+        sh = wbBack.getSheetAt(0);

 

         assertNotNull(sh.findCellComment(5, 4));

         assertNull(sh.findCellComment(5, 5));

+        

+        wb.close();

+        wbBack.close();

     }

 

-    public void testInitState(){

+    public void testInitState() throws IOException{

         HSSFWorkbook wb = new HSSFWorkbook();

         HSSFSheet sh = wb.createSheet();

         HSSFPatriarch patriarch = sh.createDrawingPatriarch();

@@ -240,11 +260,14 @@
         assertEquals(agg.getTailRecords().size(), 1);

 

         HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());

+        assertNotNull(shape);

 

         assertEquals(comment.getOptRecord().getEscherProperties().size(), 10);

+        

+        wb.close();

     }

 

-    public void testShapeId(){

+    public void testShapeId() throws IOException{

         HSSFWorkbook wb = new HSSFWorkbook();

         HSSFSheet sh = wb.createSheet();

         HSSFPatriarch patriarch = sh.createDrawingPatriarch();

@@ -252,20 +275,17 @@
         HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());

 

         comment.setShapeId(2024);

-        /**

-         * SpRecord.id == shapeId

-         * ObjRecord.id == shapeId % 1024

-         * NoteRecord.id == ObjectRecord.id == shapeId % 1024

-         */

 

         assertEquals(comment.getShapeId(), 2024);

 

         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) comment.getObjRecord().getSubRecords().get(0);

-        assertEquals(cod.getObjectId(), 1000);

+        assertEquals(2024, cod.getObjectId());

         EscherSpRecord spRecord = (EscherSpRecord) comment.getEscherContainer().getChild(0);

-        assertEquals(spRecord.getShapeId(), 2024);

-        assertEquals(comment.getShapeId(), 2024);

-        assertEquals(comment.getNoteRecord().getShapeId(), 1000);

+        assertEquals(2024, spRecord.getShapeId(), 2024);

+        assertEquals(2024, comment.getShapeId(), 2024);

+        assertEquals(2024, comment.getNoteRecord().getShapeId());

+        

+        wb.close();

     }

     

     public void testAttemptToSave2CommentsWithSameCoordinates(){

diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java
index 36a48f4..7c78fb0 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java
@@ -30,10 +30,8 @@
 import org.apache.poi.hssf.record.FormulaRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.StringRecord;
-import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.usermodel.BaseTestCell;
 import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.ErrorConstants;
 import org.apache.poi.ss.usermodel.FormulaError;
 import org.apache.poi.ss.usermodel.RichTextString;
 import org.apache.poi.ss.usermodel.Row;
@@ -330,7 +328,7 @@
 		// string to error code
 		cell.setCellValue("abc");
 		confirmStringRecord(sheet, true);
-		cell.setCellErrorValue((byte)ErrorConstants.ERROR_REF);
+		cell.setCellErrorValue(FormulaError.REF.getCode());
 		confirmStringRecord(sheet, false);
 
 		// string to boolean
@@ -356,38 +354,6 @@
 		assertEquals(DBCellRecord.class, dbcr.getClass());
 	}
 
-	/**
-	 *  The maximum length of cell contents (text) is 32,767 characters.
-	 * @throws IOException 
-	 */
-	public void testMaxTextLength() throws IOException{
-		HSSFWorkbook wb = new HSSFWorkbook();
-        HSSFSheet sheet = wb.createSheet();
-		HSSFCell cell = sheet.createRow(0).createCell(0);
-
-		int maxlen = SpreadsheetVersion.EXCEL97.getMaxTextLength();
-		assertEquals(32767, maxlen);
-
-		StringBuffer b = new StringBuffer() ;
-
-		// 32767 is okay
-		for( int i = 0 ; i < maxlen ; i++ )
-		{
-			b.append( "X" ) ;
-		}
-		cell.setCellValue(b.toString());
-
-		b.append("X");
-		// 32768 produces an invalid XLS file
-		try {
-			cell.setCellValue(b.toString());
-			fail("Expected exception");
-		} catch (IllegalArgumentException e){
-			assertEquals("The maximum length of cell contents (text) is 32,767 characters", e.getMessage());
-		}
-		wb.close();
-	}
-
     /**
      * HSSF prior to version 3.7 had a bug: it could write a NaN but could not read such a file back.
      */
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java
index 055f21b..32ca5b5 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java
@@ -17,10 +17,19 @@
 package org.apache.poi.hssf.usermodel;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import org.apache.poi.hssf.HSSFITestDataProvider;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.ss.usermodel.BaseTestCellComment;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.RichTextString;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.junit.Test;
 
 /**
@@ -75,4 +84,108 @@
         comment = cell.getCellComment();
         assertEquals("c6", comment.getString().getString());
     }
+    
+    @Test
+    public void testBug56380InsertComments() throws Exception {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        Sheet sheet = workbook.createSheet();
+        Drawing drawing = sheet.createDrawingPatriarch();
+        int noOfRows = 1025;
+        String comment = "c";
+        
+        for(int i = 0; i < noOfRows; i++) {
+            Row row = sheet.createRow(i);
+            Cell cell = row.createCell(0);
+            insertComment(drawing, cell, comment + i);
+        }
+
+        // assert that the comments are created properly before writing
+        checkComments(sheet, noOfRows, comment);
+
+        /*// store in temp-file
+        OutputStream fs = new FileOutputStream("/tmp/56380.xls");
+        try {
+            sheet.getWorkbook().write(fs);
+        } finally {
+            fs.close();
+        }*/
+        
+        // save and recreate the workbook from the saved file
+        HSSFWorkbook workbookBack = HSSFTestDataSamples.writeOutAndReadBack(workbook);
+        sheet = workbookBack.getSheetAt(0);
+        
+        // assert that the comments are created properly after reading back in
+        checkComments(sheet, noOfRows, comment);
+        
+        workbook.close();
+        workbookBack.close();
+    }
+
+    @Test
+    public void testBug56380InsertTooManyComments() throws Exception {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        try {
+            Sheet sheet = workbook.createSheet();
+            Drawing drawing = sheet.createDrawingPatriarch();
+            String comment = "c";
+    
+            for(int rowNum = 0;rowNum < 258;rowNum++) {
+            	sheet.createRow(rowNum);
+            }
+            
+            // should still work, for some reason DrawingManager2.allocateShapeId() skips the first 1024...
+            for(int count = 1025;count < 65535;count++) {
+            	int rowNum = count / 255;
+            	int cellNum = count % 255;
+                Cell cell = sheet.getRow(rowNum).createCell(cellNum);
+                try {
+                	Comment commentObj = insertComment(drawing, cell, comment + cellNum);
+                	
+                	assertEquals(count, ((HSSFComment)commentObj).getNoteRecord().getShapeId());
+                } catch (IllegalArgumentException e) {
+                	throw new IllegalArgumentException("While adding shape number " + count, e);
+                }
+            }        	
+            
+            // this should now fail to insert
+            Row row = sheet.createRow(257);
+            Cell cell = row.createCell(0);
+            insertComment(drawing, cell, comment + 0);
+        } finally {
+        	workbook.close();
+        }
+    }
+
+    private void checkComments(Sheet sheet, int noOfRows, String comment) {
+        for(int i = 0; i < noOfRows; i++) {
+            assertNotNull(sheet.getRow(i));
+            assertNotNull(sheet.getRow(i).getCell(0));
+            assertNotNull("Did not get a Cell Comment for row " + i, sheet.getRow(i).getCell(0).getCellComment());
+            assertNotNull(sheet.getRow(i).getCell(0).getCellComment().getString());
+            assertEquals(comment + i, sheet.getRow(i).getCell(0).getCellComment().getString().getString());
+        }
+    }
+
+    private Comment insertComment(Drawing drawing, Cell cell, String message) {
+        CreationHelper factory = cell.getSheet().getWorkbook().getCreationHelper();
+        
+        ClientAnchor anchor = factory.createClientAnchor();
+        anchor.setCol1(cell.getColumnIndex());
+        anchor.setCol2(cell.getColumnIndex() + 1);
+        anchor.setRow1(cell.getRowIndex());
+        anchor.setRow2(cell.getRowIndex() + 1);
+        anchor.setDx1(100); 
+        anchor.setDx2(100);
+        anchor.setDy1(100);
+        anchor.setDy2(100);
+            
+        Comment comment = drawing.createCellComment(anchor);
+        
+        RichTextString str = factory.createRichTextString(message);
+        comment.setString(str);
+        comment.setAuthor("fanfy");
+        cell.setCellComment(comment);
+        
+        return comment;
+    }    
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java
index 8cd3cba..697f350 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java
@@ -22,23 +22,33 @@
 import java.io.IOException;
 
 import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting;
+import org.apache.poi.ss.usermodel.Color;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
 import org.apache.poi.ss.usermodel.Workbook;
 
 /**
- *
- * @author Dmitriy Kumshayev
+ * HSSF-specific Conditional Formatting tests
  */
 public final class TestHSSFConditionalFormatting extends BaseTestConditionalFormatting {
     public TestHSSFConditionalFormatting(){
         super(HSSFITestDataProvider.instance);
     }
+    protected void assertColour(String hexExpected, Color actual) {
+        assertNotNull("Colour must be given", actual);
+        HSSFColor colour = (HSSFColor)actual;
+        assertEquals(hexExpected, colour.getHexString());
+    }
 
-    public void testRead(){
+    public void testRead() {
         testRead("WithConditionalFormatting.xls");
     }
+    
+    public void testReadOffice2007() {
+        testReadOffice2007("NewStyleConditionalFormattings.xls");
+    }
 
     public void test53691() throws IOException {
         SheetConditionalFormatting cf;
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
index f5ea7a1..2e34d6f 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
@@ -17,9 +17,7 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 import java.io.IOException;
 import java.text.ParseException;
@@ -349,6 +347,7 @@
         HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("DateFormats.xls");
         HSSFSheet sheet       = workbook.getSheetAt(0);
         InternalWorkbook wb           = workbook.getWorkbook();
+        assertNotNull(wb);
 
         HSSFRow  row;
         HSSFCell cell;
@@ -482,6 +481,25 @@
     }
 
     @Test
+    public void absoluteDayYearTooLow() {
+        GregorianCalendar calendar = new GregorianCalendar(1899, 0, 1);
+        try {
+        	HSSFDateUtil.absoluteDay(calendar, false);
+        	fail("Should fail here");
+        } catch (IllegalArgumentException e) {
+        	// expected here
+        }
+
+        try {
+            calendar = new GregorianCalendar(1903, 0, 1);
+            HSSFDateUtil.absoluteDay(calendar, true);
+        	fail("Should fail here");
+        } catch (IllegalArgumentException e) {
+        	// expected here
+        }
+    }
+
+    @Test
     public void convertTime() {
 
         final double delta = 1E-7; // a couple of digits more accuracy than strictly required
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
index 654db6a..dafb481 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import java.io.IOException;
+
 import junit.framework.AssertionFailedError;
 
 import org.apache.poi.hssf.HSSFITestDataProvider;
@@ -71,7 +73,7 @@
         assertEquals(-1, row.getLastCellNum());
     }
 
-    public void testMoveCell() {
+    public void testMoveCell() throws IOException {
         HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet sheet = workbook.createSheet();
         HSSFRow row = sheet.createRow(0);
@@ -115,9 +117,11 @@
         assertEquals(5, cellB2.getColumnIndex());
         assertEquals(2, row.getFirstCellNum());
         assertEquals(6, row.getLastCellNum());
+        
+        workbook.close();
     }
 
-    public void testRowHeight(){
+    public void testRowHeight() throws IOException{
         HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet sheet = workbook.createSheet();
         HSSFRow row = sheet.createRow(0);
@@ -132,5 +136,7 @@
         row.setHeight((short) -1);
         assertEquals(row.getHeight(), sheet.getDefaultRowHeight());
         assertEquals(row.getRowRecord().getBadFontHeight(), false);
+        
+        workbook.close();
     }
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
index 2fabba9..efe4f01 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
@@ -28,6 +28,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -1106,4 +1107,36 @@
 	private void expectName(HSSFWorkbook wb, String name, String expect) {
 		assertEquals(expect, wb.getName(name).getRefersToFormula());
 	}
+
+	@Test
+	public void test49423() throws Exception
+    {
+		HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("49423.xls");
+		
+		boolean found = false;
+        int numSheets = workbook.getNumberOfSheets();
+        for (int i = 0; i < numSheets; i++) {
+            HSSFSheet sheet = workbook.getSheetAt(i);
+            List<HSSFShape> shapes = sheet.getDrawingPatriarch().getChildren();
+            for(HSSFShape shape : shapes){
+                HSSFAnchor anchor = shape.getAnchor();
+    
+                if(anchor instanceof HSSFClientAnchor){
+                    // absolute coordinates
+                    HSSFClientAnchor clientAnchor = (HSSFClientAnchor)anchor;
+                    assertNotNull(clientAnchor);
+                    //System.out.println(clientAnchor.getRow1() + "," + clientAnchor.getRow2());
+                    found = true;
+                } else if (anchor instanceof HSSFChildAnchor){
+                    // shape is grouped and the anchor is expressed in the coordinate system of the group 
+                    HSSFChildAnchor childAnchor = (HSSFChildAnchor)anchor;
+                    assertNotNull(childAnchor);
+                    //System.out.println(childAnchor.getDy1() + "," + childAnchor.getDy2());
+                    found = true;
+                }
+            }
+        }
+        
+        assertTrue("Should find some images via Client or Child anchors, but did not find any at all", found);
+    }
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestUnfixedBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestUnfixedBugs.java
index 2615545..d0efcb0 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestUnfixedBugs.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestUnfixedBugs.java
@@ -17,8 +17,6 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import static org.junit.Assert.assertEquals;
-
 import java.io.IOException;
 
 import junit.framework.AssertionFailedError;
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestDocument.java b/src/testcases/org/apache/poi/poifs/filesystem/TestDocument.java
index e216ed9..21494b3 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestDocument.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestDocument.java
@@ -28,27 +28,25 @@
 import org.apache.poi.poifs.storage.SmallDocumentBlock;
 
 /**
- * Class to test POIFSDocument functionality
- *
- * @author Marc Johnson
+ * Class to test OPOIFSDocument functionality
  */
 public final class TestDocument extends TestCase {
 
     /**
      * Integration test -- really about all we can do
      */
-    public void testPOIFSDocument() throws IOException {
+    public void testOPOIFSDocument() throws IOException {
 
         // verify correct number of blocks get created for document
         // that is exact multituple of block size
-        POIFSDocument document;
+        OPOIFSDocument document;
         byte[]        array = new byte[ 4096 ];
 
         for (int j = 0; j < array.length; j++)
         {
             array[ j ] = ( byte ) j;
         }
-        document = new POIFSDocument("foo", new SlowInputStream(new ByteArrayInputStream(array)));
+        document = new OPOIFSDocument("foo", new SlowInputStream(new ByteArrayInputStream(array)));
         checkDocument(document, array);
 
         // verify correct number of blocks get created for document
@@ -58,7 +56,7 @@
         {
             array[ j ] = ( byte ) j;
         }
-        document = new POIFSDocument("bar", new ByteArrayInputStream(array));
+        document = new OPOIFSDocument("bar", new ByteArrayInputStream(array));
         checkDocument(document, array);
 
         // verify correct number of blocks get created for document
@@ -68,7 +66,7 @@
         {
             array[ j ] = ( byte ) j;
         }
-        document = new POIFSDocument("_bar", new ByteArrayInputStream(array));
+        document = new OPOIFSDocument("_bar", new ByteArrayInputStream(array));
         checkDocument(document, array);
 
         // verify correct number of blocks get created for document
@@ -78,7 +76,7 @@
         {
             array[ j ] = ( byte ) j;
         }
-        document = new POIFSDocument("_bar2",
+        document = new OPOIFSDocument("_bar2",
                                      new ByteArrayInputStream(array));
         checkDocument(document, array);
 
@@ -88,7 +86,7 @@
         {
             array[ j ] = ( byte ) j;
         }
-        document = new POIFSDocument("foobar",
+        document = new OPOIFSDocument("foobar",
                                      new ByteArrayInputStream(array));
         checkDocument(document, array);
         document.setStartBlock(0x12345678);   // what a big file!!
@@ -135,9 +133,9 @@
         }
     }
 
-    private static POIFSDocument makeCopy(POIFSDocument document, byte[] input, byte[] data)
+    private static OPOIFSDocument makeCopy(OPOIFSDocument document, byte[] input, byte[] data)
             throws IOException {
-        POIFSDocument copy = null;
+        OPOIFSDocument copy = null;
 
         if (input.length >= 4096)
         {
@@ -156,12 +154,12 @@
                 }
                 blocks[ index++ ] = block;
             }
-            copy = new POIFSDocument("test" + input.length, blocks,
+            copy = new OPOIFSDocument("test" + input.length, blocks,
                                      input.length);
         }
         else
         {
-            copy = new POIFSDocument(
+            copy = new OPOIFSDocument(
                 "test" + input.length,
                 ( SmallDocumentBlock [] ) document.getSmallBlocks(),
                 input.length);
@@ -169,7 +167,7 @@
         return copy;
     }
 
-    private static void checkDocument(final POIFSDocument document, final byte[] input)
+    private static void checkDocument(final OPOIFSDocument document, final byte[] input)
             throws IOException {
         int big_blocks   = 0;
         int small_blocks = 0;
@@ -195,7 +193,7 @@
     }
 
     private static byte[] checkValues(int big_blocks, int small_blocks, int total_output,
-            POIFSDocument document, byte[] input) throws IOException {
+            OPOIFSDocument document, byte[] input) throws IOException {
         assertEquals(document, document.getDocumentProperty().getDocument());
         int increment = ( int ) Math.sqrt(input.length);
 
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java
index 6ba10f9..8019358 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java
@@ -31,10 +31,7 @@
 
 /**
  * Class to test DocumentInputStream functionality
- *
- * @author Marc Johnson
  */
-
 public final class TestDocumentInputStream extends TestCase {
    private DocumentNode     _workbook_n;
    private DocumentNode     _workbook_o;
@@ -64,8 +61,8 @@
         {
             rawBlocks[ j ] = new RawDataBlock(stream);
         }
-        POIFSDocument document = new POIFSDocument("Workbook", rawBlocks,
-                                                   _workbook_size);
+        OPOIFSDocument document = new OPOIFSDocument("Workbook", rawBlocks,
+                                                     _workbook_size);
 
         _workbook_o = new DocumentNode(
             document.getDocumentProperty(),
@@ -95,7 +92,7 @@
      * test constructor
      */
     public void testConstructor() throws IOException {
-        DocumentInputStream ostream = new DocumentInputStream(_workbook_o);
+        DocumentInputStream ostream = new ODocumentInputStream(_workbook_o);
         DocumentInputStream nstream = new NDocumentInputStream(_workbook_n);
         
         assertEquals(_workbook_size, _workbook_o.getSize());
@@ -103,6 +100,9 @@
 
         assertEquals(_workbook_size, ostream.available());
         assertEquals(_workbook_size, nstream.available());
+        
+        ostream.close();
+        nstream.close();
     }
 
     /**
@@ -514,12 +514,14 @@
        
        NPOIFSFileSystem npoifs = new NPOIFSFileSystem(sample);
        try {
-           POIFSFileSystem  opoifs = new POIFSFileSystem(new FileInputStream(sample));
+           OPOIFSFileSystem  opoifs = new OPOIFSFileSystem(new FileInputStream(sample));
            
            // Ensure we have what we expect on the root
            assertEquals(npoifs, npoifs.getRoot().getNFileSystem());
-           assertEquals(null,   npoifs.getRoot().getFileSystem());
-           assertEquals(opoifs, opoifs.getRoot().getFileSystem());
+           assertEquals(npoifs, npoifs.getRoot().getFileSystem());
+           assertEquals(null,   npoifs.getRoot().getOFileSystem());
+           assertEquals(null,   opoifs.getRoot().getFileSystem());
+           assertEquals(opoifs, opoifs.getRoot().getOFileSystem());
            assertEquals(null,   opoifs.getRoot().getNFileSystem());
            
            // Check inside
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentNode.java b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentNode.java
index 6101494..69d1677 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentNode.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentNode.java
@@ -46,7 +46,7 @@
         {
             rawBlocks[ j ] = new RawDataBlock(stream);
         }
-        POIFSDocument    document  = new POIFSDocument("document", rawBlocks,
+        OPOIFSDocument   document  = new OPOIFSDocument("document", rawBlocks,
                                          2000);
         DocumentProperty property2 = document.getDocumentProperty();
         DirectoryNode    parent    = new DirectoryNode(property1, (POIFSFileSystem)null, null);
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestFileSystemBugs.java b/src/testcases/org/apache/poi/poifs/filesystem/TestFileSystemBugs.java
new file mode 100644
index 0000000..2f7c67f
--- /dev/null
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestFileSystemBugs.java
@@ -0,0 +1,186 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.filesystem;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+
+/**
+ * Tests bugs across both POIFSFileSystem and NPOIFSFileSystem
+ */
+public final class TestFileSystemBugs extends TestCase {
+    protected static POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
+    protected static POIDataSamples _ssSamples = POIDataSamples.getSpreadSheetInstance();
+    
+    protected List<NPOIFSFileSystem> openedFSs;
+    protected void tearDown() throws Exception {
+        if (openedFSs != null && !openedFSs.isEmpty()) {
+            for (NPOIFSFileSystem fs : openedFSs) {
+                try {
+                    fs.close();
+                } catch (Exception e) {
+                    System.err.println("Error closing FS: " + e);
+                }
+            }
+        }
+        openedFSs = null;
+    }
+    protected DirectoryNode[] openSample(String name, boolean oldFails) throws Exception {
+        return openSamples(new InputStream[] {
+                _samples.openResourceAsStream(name),
+                _samples.openResourceAsStream(name)
+        }, oldFails);
+    }
+    protected DirectoryNode[] openSSSample(String name, boolean oldFails) throws Exception {
+        return openSamples(new InputStream[] {
+                _ssSamples.openResourceAsStream(name),
+                _ssSamples.openResourceAsStream(name)
+        }, oldFails);
+    }
+    protected DirectoryNode[] openSamples(InputStream[] inps, boolean oldFails) throws Exception {
+        NPOIFSFileSystem nfs = new NPOIFSFileSystem(inps[0]);
+        if (openedFSs == null) openedFSs = new ArrayList<NPOIFSFileSystem>();
+        openedFSs.add(nfs);
+        
+        OPOIFSFileSystem ofs = null;
+        try {
+            ofs = new OPOIFSFileSystem(inps[1]);
+            if (oldFails) fail("POIFSFileSystem should have failed but didn't");
+        } catch (Exception e) {
+            if (!oldFails) throw e;
+        }
+
+        if (ofs == null) return new DirectoryNode[] { nfs.getRoot() };
+        return new DirectoryNode[] { ofs.getRoot(), nfs.getRoot() };
+    }
+
+    /**
+     * Test that we can open files that come via Lotus notes.
+     * These have a top level directory without a name....
+     */
+    public void testNotesOLE2Files() throws Exception {
+        // Check the contents
+        for (DirectoryNode root : openSample("Notes.ole2", false)) {
+            assertEquals(1, root.getEntryCount());
+
+            Entry entry = root.getEntries().next();
+            assertTrue(entry.isDirectoryEntry());
+            assertTrue(entry instanceof DirectoryEntry);
+
+            // The directory lacks a name!
+            DirectoryEntry dir = (DirectoryEntry)entry;
+            assertEquals("", dir.getName());
+
+            // Has two children
+            assertEquals(2, dir.getEntryCount());
+
+            // Check them
+            Iterator<Entry> it = dir.getEntries();
+            entry = it.next();
+            assertEquals(true, entry.isDocumentEntry());
+            assertEquals("\u0001Ole10Native", entry.getName());
+
+            entry = it.next();
+            assertEquals(true, entry.isDocumentEntry());
+            assertEquals("\u0001CompObj", entry.getName());
+        }
+    }
+    
+    /**
+     * Ensure that a file with a corrupted property in the
+     *  properties table can still be loaded, and the remaining
+     *  properties used
+     * Note - only works for NPOIFSFileSystem, POIFSFileSystem
+     *  can't cope with this level of corruption
+     */
+    public void testCorruptedProperties() throws Exception {
+        for (DirectoryNode root : openSample("unknown_properties.msg", true)) {
+            assertEquals(42, root.getEntryCount());
+        }
+    }
+    
+    /**
+     * With heavily nested documents, ensure we still re-write the same
+     */
+    public void testHeavilyNestedReWrite() throws Exception {
+        for (DirectoryNode root : openSSSample("ex42570-20305.xls", false)) {
+            // Record the structure
+            Map<String,Integer> entries = new HashMap<String, Integer>();
+            fetchSizes("/", root, entries);
+            
+            // Prepare to copy
+            DirectoryNode dest;
+            if (root.getNFileSystem() != null) {
+                dest = (new NPOIFSFileSystem()).getRoot();
+            } else {
+                dest = (new OPOIFSFileSystem()).getRoot();
+            }
+            
+            // Copy over
+            EntryUtils.copyNodes(root, dest);
+            
+            // Re-load, always as NPOIFS
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            if (root.getNFileSystem() != null) {
+                root.getNFileSystem().writeFilesystem(baos);
+            } else {
+                root.getOFileSystem().writeFilesystem(baos);
+            }
+            NPOIFSFileSystem read = new NPOIFSFileSystem(
+                    new ByteArrayInputStream(baos.toByteArray()));
+            
+            // Check the structure matches
+            checkSizes("/", read.getRoot(), entries);
+        }
+    }
+    private void fetchSizes(String path, DirectoryNode dir, Map<String,Integer> entries) {
+        for (Entry entry : dir) {
+            if (entry instanceof DirectoryNode) {
+                String ourPath = path + entry.getName() + "/";
+                entries.put(ourPath, -1);
+                fetchSizes(ourPath, (DirectoryNode)entry, entries);
+            } else {
+                DocumentNode doc = (DocumentNode)entry;
+                entries.put(path+entry.getName(), doc.getSize());
+            }
+        }
+    }
+    private void checkSizes(String path, DirectoryNode dir, Map<String,Integer> entries) {
+        for (Entry entry : dir) {
+            if (entry instanceof DirectoryNode) {
+                String ourPath = path + entry.getName() + "/";
+                assertTrue(entries.containsKey(ourPath));
+                assertEquals(-1, entries.get(ourPath).intValue());
+                checkSizes(ourPath, (DirectoryNode)entry, entries);
+            } else {
+                DocumentNode doc = (DocumentNode)entry;
+                assertEquals(entries.get(path+entry.getName()).intValue(), doc.getSize());
+            }
+        }
+    }
+}
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
index b5793a2..ed598ed 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
@@ -20,6 +20,7 @@
 import static org.hamcrest.core.IsCollectionContaining.hasItem;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
@@ -935,27 +936,27 @@
       DocumentEntry miniDoc;
       DocumentEntry normDoc;
       
-      // Initially has a BAT but not SBAT
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+      // Initially has Properties + BAT but not SBAT
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
       
       // Check that the SBAT is empty
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
       
-      // Check that no properties table has been written yet
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs._get_property_table().getStartBlock());
+      // Check that properties table was given block 0
+      assertEquals(0, fs._get_property_table().getStartBlock());
 
       // Write and read it
       fs = writeOutAndReadBack(fs);
       
-      // Property table entries have been added to the blocks 
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(3));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
-      assertEquals(2, fs._get_property_table().getStartBlock());
+      // No change, SBAT remains empty 
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(2));
+      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(3));
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getRoot().getProperty().getStartBlock());
+      assertEquals(0, fs._get_property_table().getStartBlock());
 
       
       // Put everything within a new directory
@@ -967,19 +968,19 @@
       main4096[4095] = -11;
       testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
 
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+      assertEquals(3, fs.getNextBlock(2));
       assertEquals(4, fs.getNextBlock(3));
       assertEquals(5, fs.getNextBlock(4));
       assertEquals(6, fs.getNextBlock(5));
       assertEquals(7, fs.getNextBlock(6));
       assertEquals(8, fs.getNextBlock(7));
       assertEquals(9, fs.getNextBlock(8));
-      assertEquals(10, fs.getNextBlock(9));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(9));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(11));
-      
+      // SBAT still unused
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
 
       
@@ -989,18 +990,18 @@
       main5124[5123] = -33;
       testDir.createDocument("Normal5124", new ByteArrayInputStream(main5124));
 
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+      assertEquals(3, fs.getNextBlock(2));
       assertEquals(4, fs.getNextBlock(3));
       assertEquals(5, fs.getNextBlock(4));
       assertEquals(6, fs.getNextBlock(5));
       assertEquals(7, fs.getNextBlock(6));
       assertEquals(8, fs.getNextBlock(7));
       assertEquals(9, fs.getNextBlock(8));
-      assertEquals(10, fs.getNextBlock(9));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(9));
 
+      assertEquals(11, fs.getNextBlock(10));
       assertEquals(12, fs.getNextBlock(11));
       assertEquals(13, fs.getNextBlock(12));
       assertEquals(14, fs.getNextBlock(13));
@@ -1010,8 +1011,8 @@
       assertEquals(18, fs.getNextBlock(17));
       assertEquals(19, fs.getNextBlock(18));
       assertEquals(20, fs.getNextBlock(19));
-      assertEquals(21, fs.getNextBlock(20));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(20));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(21));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(22));
 
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getRoot().getProperty().getStartBlock());
@@ -1022,18 +1023,18 @@
       testDir.createDocument("Mini", new ByteArrayInputStream(mini));
       
       // Mini stream will get one block for fat + one block for data
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+      assertEquals(3, fs.getNextBlock(2));
       assertEquals(4, fs.getNextBlock(3));
       assertEquals(5, fs.getNextBlock(4));
       assertEquals(6, fs.getNextBlock(5));
       assertEquals(7, fs.getNextBlock(6));
       assertEquals(8, fs.getNextBlock(7));
       assertEquals(9, fs.getNextBlock(8));
-      assertEquals(10, fs.getNextBlock(9));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(9));
 
+      assertEquals(11, fs.getNextBlock(10));
       assertEquals(12, fs.getNextBlock(11));
       assertEquals(13, fs.getNextBlock(12));
       assertEquals(14, fs.getNextBlock(13));
@@ -1043,15 +1044,14 @@
       assertEquals(18, fs.getNextBlock(17));
       assertEquals(19, fs.getNextBlock(18));
       assertEquals(20, fs.getNextBlock(19));
-      assertEquals(21, fs.getNextBlock(20));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(20));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(23));
 
       // Check the mini stream location was set
-      // (22 is mini fat, 23 is first mini stream block)
-      assertEquals(23, fs.getRoot().getProperty().getStartBlock());
+      // (21 is mini fat, 22 is first mini stream block)
+      assertEquals(22, fs.getRoot().getProperty().getStartBlock());
       
       
       // Write and read back
@@ -1060,28 +1060,28 @@
       
       // Check the header has the right points in it
       assertEquals(1, header.getBATCount());
-      assertEquals(0, header.getBATArray()[0]);
-      assertEquals(2, header.getPropertyStart());
+      assertEquals(1, header.getBATArray()[0]);
+      assertEquals(0, header.getPropertyStart());
       assertEquals(1, header.getSBATCount());
-      assertEquals(22, header.getSBATStart());
-      assertEquals(23, fs._get_property_table().getRoot().getStartBlock());
+      assertEquals(21, header.getSBATStart());
+      assertEquals(22, fs._get_property_table().getRoot().getStartBlock());
       
       // Block use should be almost the same, except the properties
       //  stream will have grown out to cover 2 blocks
       // Check the block use is all unchanged
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(24, fs.getNextBlock(2)); // Properties now extends over 2 blocks
+      assertEquals(23, fs.getNextBlock(0)); // Properties now extends over 2 blocks
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
       
+      assertEquals(3, fs.getNextBlock(2));
       assertEquals(4, fs.getNextBlock(3));
       assertEquals(5, fs.getNextBlock(4));
       assertEquals(6, fs.getNextBlock(5));
       assertEquals(7, fs.getNextBlock(6));
       assertEquals(8, fs.getNextBlock(7));
       assertEquals(9, fs.getNextBlock(8));
-      assertEquals(10, fs.getNextBlock(9));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10)); // End of normal4096
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(9)); // End of normal4096
 
+      assertEquals(11, fs.getNextBlock(10));
       assertEquals(12, fs.getNextBlock(11));
       assertEquals(13, fs.getNextBlock(12));
       assertEquals(14, fs.getNextBlock(13));
@@ -1091,13 +1091,12 @@
       assertEquals(18, fs.getNextBlock(17));
       assertEquals(19, fs.getNextBlock(18));
       assertEquals(20, fs.getNextBlock(19));
-      assertEquals(21, fs.getNextBlock(20));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21)); // End of normal5124 
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(20)); // End of normal5124 
       
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream FAT
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23)); // Mini Stream data
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(24)); // Properties #2
-      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(25));
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21)); // Mini Stream FAT
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream data
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23)); // Properties #2
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
 
       
       // Check some data
@@ -1123,19 +1122,19 @@
       // Check - will have un-used sectors now
       fs = writeOutAndReadBack(fs);
       
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // Props back in 1 block
+      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0)); // Props back in 1 block
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
       
+      assertEquals(3, fs.getNextBlock(2));
       assertEquals(4, fs.getNextBlock(3));
       assertEquals(5, fs.getNextBlock(4));
       assertEquals(6, fs.getNextBlock(5));
       assertEquals(7, fs.getNextBlock(6));
       assertEquals(8, fs.getNextBlock(7));
       assertEquals(9, fs.getNextBlock(8));
-      assertEquals(10, fs.getNextBlock(9));
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(10)); // End of normal4096
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(9)); // End of normal4096
 
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(12));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(13));
@@ -1146,11 +1145,11 @@
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(18));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(19));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(20));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(21));
       
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream FAT
-      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(23)); // Mini Stream data
-      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24)); // Properties gone
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(21)); // Mini Stream FAT
+      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(22)); // Mini Stream data
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(23)); // Properties gone
+      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(24));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(25));
       
       // All done
@@ -1164,20 +1163,20 @@
        DocumentEntry normDoc;
        HeaderBlock hdr;
        
-       // Initially has BAT + Properties but nothing else
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+       // Initially has Properties + BAT but nothing else
+       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2));
        
        hdr = writeOutAndReadHeader(fs);
        // No mini stream, and no xbats
        // Will have fat then properties stream
        assertEquals(1, hdr.getBATCount());
-       assertEquals(0, hdr.getBATArray()[0]);
-       assertEquals(2, hdr.getPropertyStart());
+       assertEquals(1, hdr.getBATArray()[0]);
+       assertEquals(0, hdr.getPropertyStart());
        assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getSBATStart());
        assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
-       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*4, fs.size());
+       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*3, fs.size());
        
        
        // Get a clean filesystem to start with
@@ -1200,8 +1199,8 @@
 
        
        // Check the mini stream was added, then the main stream
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1)); 
+       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1)); 
        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // Mini Fat
        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3)); // Mini Stream
        assertEquals(5,                           fs.getNextBlock(4)); // Main Stream
@@ -1231,15 +1230,15 @@
        // Check the header details - will have the sbat near the start,
        //  then the properties at the end
        assertEquals(1, hdr.getBATCount());
-       assertEquals(0, hdr.getBATArray()[0]);
+       assertEquals(1, hdr.getBATArray()[0]);
        assertEquals(2, hdr.getSBATStart());
-       assertEquals(12, hdr.getPropertyStart());
+       assertEquals(0, hdr.getPropertyStart());
        assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
        
        // Check the block allocation is unchanged, other than
        //  the properties stream going in at the end
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(1));
+       assertEquals(12,                          fs.getNextBlock(0)); // Properties
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3));
        assertEquals(5,                           fs.getNextBlock(4));
@@ -1250,10 +1249,9 @@
        assertEquals(10,                          fs.getNextBlock(9));
        assertEquals(11,                          fs.getNextBlock(10));
        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
-       assertEquals(13,                          fs.getNextBlock(12));
-       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(13));
-       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(14));
-       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*15, fs.size());
+       assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(12));
+       assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(13));
+       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*14, fs.size());
        
        
        // Check the data
@@ -1304,6 +1302,138 @@
 
        normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
        assertContentsMatches(main4106, normDoc);
+       
+       // All done
+       fs.close();
+   }
+   
+   @Test
+   public void readZeroLengthEntries() throws Exception {
+       NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("only-zero-byte-streams.ole2"));
+       DirectoryNode testDir = fs.getRoot();
+       assertEquals(3, testDir.getEntryCount());
+       DocumentEntry entry;
+       
+       entry = (DocumentEntry)testDir.getEntry("test-zero-1");
+       assertNotNull(entry);
+       assertEquals(0, entry.getSize());
+       
+       entry = (DocumentEntry)testDir.getEntry("test-zero-2");
+       assertNotNull(entry);
+       assertEquals(0, entry.getSize());
+       
+       entry = (DocumentEntry)testDir.getEntry("test-zero-3");
+       assertNotNull(entry);
+       assertEquals(0, entry.getSize());
+       
+       // Check properties, all have zero length, no blocks
+       NPropertyTable props = fs._get_property_table();
+       assertEquals(POIFSConstants.END_OF_CHAIN, props.getRoot().getStartBlock());
+       for (Property prop : props.getRoot()) {
+           assertEquals("test-zero-", prop.getName().substring(0, 10));
+           assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
+       }
+       
+       // All done
+       fs.close();
+   }
+   
+   @Test
+   public void writeZeroLengthEntries() throws Exception {
+       NPOIFSFileSystem fs = new NPOIFSFileSystem();
+       DirectoryNode testDir = fs.getRoot();
+       DocumentEntry miniDoc;
+       DocumentEntry normDoc;
+       DocumentEntry emptyDoc;
+       
+       // Add mini and normal sized entries to start
+       byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
+       testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
+       
+       // Add to the main stream
+       byte[] main4106 = new byte[4106];
+       main4106[0] = 41;
+       main4106[4105] = 42;
+       testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
+       
+       // Now add some empty ones
+       byte[] empty = new byte[0];
+       testDir.createDocument("empty-1", new ByteArrayInputStream(empty));
+       testDir.createDocument("empty-2", new ByteArrayInputStream(empty));
+       testDir.createDocument("empty-3", new ByteArrayInputStream(empty));
+       
+       // Check
+       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
+       assertContentsMatches(mini2, miniDoc);
+
+       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
+       assertContentsMatches(main4106, normDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
+       assertContentsMatches(empty, emptyDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
+       assertContentsMatches(empty, emptyDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
+       assertContentsMatches(empty, emptyDoc);
+       
+       // Look at the properties entry, and check the empty ones
+       //  have zero size and no start block
+       NPropertyTable props = fs._get_property_table();
+       Iterator<Property> propsIt = props.getRoot().getChildren();
+       
+       Property prop = propsIt.next();
+       assertEquals("Mini2", prop.getName());
+       assertEquals(0, prop.getStartBlock());
+       assertEquals(7, prop.getSize());
+       
+       prop = propsIt.next();
+       assertEquals("Normal4106", prop.getName());
+       assertEquals(4, prop.getStartBlock()); // BAT, Props, SBAT, MIni
+       assertEquals(4106, prop.getSize());
+       
+       prop = propsIt.next();
+       assertEquals("empty-1", prop.getName());
+       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
+       assertEquals(0, prop.getSize());
+       
+       prop = propsIt.next();
+       assertEquals("empty-2", prop.getName());
+       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
+       assertEquals(0, prop.getSize());
+       
+       prop = propsIt.next();
+       assertEquals("empty-3", prop.getName());
+       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
+       assertEquals(0, prop.getSize());
+       
+       
+       // Save and re-check
+       fs = writeOutAndReadBack(fs);
+       testDir = fs.getRoot();
+       
+       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
+       assertContentsMatches(mini2, miniDoc);
+
+       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
+       assertContentsMatches(main4106, normDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
+       assertContentsMatches(empty, emptyDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
+       assertContentsMatches(empty, emptyDoc);
+       
+       emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
+       assertContentsMatches(empty, emptyDoc);
+       
+       // Check that a mini-stream was assigned, with one block used
+       assertEquals(3, testDir.getProperty().getStartBlock()); 
+       assertEquals(64, testDir.getProperty().getSize()); 
+       
+       // All done
+       fs.close();
    }
 
    /**
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java
index c875c52..4f10208 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSMiniStore.java
@@ -17,18 +17,19 @@
 
 package org.apache.poi.poifs.filesystem;
 
+import java.io.ByteArrayInputStream;
 import java.nio.ByteBuffer;
 import java.util.Iterator;
 
-import junit.framework.TestCase;
-
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.POITestCase;
 import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.IOUtils;
 
 /**
  * Tests for the Mini Store in the NIO POIFS
  */
-public final class TestNPOIFSMiniStore extends TestCase {
+public final class TestNPOIFSMiniStore extends POITestCase {
    private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
    
    /**
@@ -332,4 +333,130 @@
       
       fs.close();
    }
+   
+   public void testCreateMiniStoreFirst() throws Exception {
+       NPOIFSFileSystem fs = new NPOIFSFileSystem();
+       NPOIFSMiniStore ministore = fs.getMiniStore();
+       DocumentInputStream dis;
+       DocumentEntry entry;
+
+       // Initially has Properties + BAT but nothing else
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(2));
+       // Ministore has no blocks, so can't iterate until used
+       try {
+           ministore.getNextBlock(0);
+       } catch (IndexOutOfBoundsException e) {}
+       
+       // Write a very small new document, will populate the ministore for us
+       byte[] data = new byte[8];
+       for (int i=0; i<data.length; i++) {
+           data[i] = (byte)(i+42);
+       }
+       fs.getRoot().createDocument("mini", new ByteArrayInputStream(data));
+       
+       // Should now have a mini-fat and a mini-stream
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,fs.getNextBlock(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(2));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(3));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,    fs.getNextBlock(4));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    ministore.getNextBlock(0));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,    ministore.getNextBlock(1));
+       
+       // Re-fetch the mini store, and add it a second time
+       ministore = fs.getMiniStore();
+       fs.getRoot().createDocument("mini2", new ByteArrayInputStream(data));
+       
+       // Main unchanged, ministore has a second
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,fs.getNextBlock(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(2));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    fs.getNextBlock(3));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,    fs.getNextBlock(4));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    ministore.getNextBlock(0));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    ministore.getNextBlock(1));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,    ministore.getNextBlock(2));
+       
+       // Check the data is unchanged and the right length
+       entry = (DocumentEntry)fs.getRoot().getEntry("mini");
+       assertEquals(data.length, entry.getSize());
+       byte[] rdata = new byte[data.length];
+       dis = new DocumentInputStream(entry);
+       IOUtils.readFully(dis, rdata);
+       assertEquals(data, rdata);
+       dis.close();
+       
+       entry = (DocumentEntry)fs.getRoot().getEntry("mini2");
+       assertEquals(data.length, entry.getSize());
+       rdata = new byte[data.length];
+       dis = new DocumentInputStream(entry);
+       IOUtils.readFully(dis, rdata);
+       assertEquals(data, rdata);
+       dis.close();
+
+       // Done
+       fs.close();
+   }
+   
+   public void testMultiBlockStream() throws Exception {
+       byte[] data1B = new byte[63];
+       byte[] data2B = new byte[64+14];
+       for (int i=0; i<data1B.length; i++) {
+           data1B[i] = (byte)(i+2);
+       }
+       for (int i=0; i<data2B.length; i++) {
+           data2B[i] = (byte)(i+4);
+       }
+       
+       // New filesystem and store to use
+       NPOIFSFileSystem fs = new NPOIFSFileSystem();
+       NPOIFSMiniStore ministore = fs.getMiniStore();
+
+       // Initially has Properties + BAT but nothing else
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(2));
+       
+       // Store the 2 block one, should use 2 mini blocks, and request
+       // the use of 2 big blocks
+       ministore = fs.getMiniStore();
+       fs.getRoot().createDocument("mini2", new ByteArrayInputStream(data2B));
+       
+       // Check
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(2)); // SBAT
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(3)); // Mini
+       assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(4));
+       
+       // First 2 Mini blocks will be used
+       assertEquals(2, ministore.getFreeBlock());
+       
+       // Add one more mini-stream, and check
+       fs.getRoot().createDocument("mini1", new ByteArrayInputStream(data1B));
+       
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(2)); // SBAT
+       assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(3)); // Mini
+       assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(4));
+       
+       // One more mini-block will be used
+       assertEquals(3, ministore.getFreeBlock());
+       
+       // Check the contents too
+       byte[] r1 = new byte[data1B.length];
+       DocumentInputStream dis = fs.createDocumentInputStream("mini1");
+       IOUtils.readFully(dis, r1);
+       dis.close();
+       assertEquals(data1B, r1);
+       
+       byte[] r2 = new byte[data2B.length];
+       dis = fs.createDocumentInputStream("mini2");
+       IOUtils.readFully(dis, r2);
+       dis.close();
+       assertEquals(data2B, r2);
+   }
 }
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java
index 1dcdba1..f1c8c18 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSStream.java
@@ -860,12 +860,12 @@
       NPOIFSFileSystem fs = new NPOIFSFileSystem();
       NPOIFSStream stream = new NPOIFSStream(fs);
       
-      // Check our filesystem has a BAT and the Properties
+      // Check our filesystem has Properties then BAT
       assertEquals(2, fs.getFreeBlock());
       BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
+      assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(2));
       
       // Check the stream as-is
       assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
@@ -887,11 +887,11 @@
       // Check now
       assertEquals(4, fs.getFreeBlock());
       bat = fs.getBATBlockAndIndex(0).getBlock();
-      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
-      assertEquals(3,                           bat.getValueAt(2));
-      assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3));
-      assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
+      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
+      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
+      assertEquals(3,                              bat.getValueAt(2));
+      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(3));
+      assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(4));
       
       
       Iterator<ByteBuffer> it = stream.getBlockIterator();
@@ -927,11 +927,11 @@
    public void testWriteThenReplace() throws Exception {
        NPOIFSFileSystem fs = new NPOIFSFileSystem();
 
-       // Starts empty
+       // Starts empty, other that Properties and BAT
        BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
-       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2));
+       assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
+       assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(2));
 
        // Write something that uses a main stream
        byte[] main4106 = new byte[4106];
@@ -941,8 +941,8 @@
                "Normal", new ByteArrayInputStream(main4106));
        
        // Should have used 9 blocks
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
        assertEquals(3,                           bat.getValueAt(2));
        assertEquals(4,                           bat.getValueAt(3));
        assertEquals(5,                           bat.getValueAt(4));
@@ -969,8 +969,8 @@
        nout.close();
        
        // Will have dropped to 8
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
        assertEquals(3,                           bat.getValueAt(2));
        assertEquals(4,                           bat.getValueAt(3));
        assertEquals(5,                           bat.getValueAt(4));
@@ -991,9 +991,9 @@
        fs = writeOutAndReadBack(fs);
        bat = fs.getBATBlockAndIndex(0).getBlock();
        
-       // Will have properties, but otherwise the same
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       // No change after write
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); // Properties
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
        assertEquals(3,                           bat.getValueAt(2));
        assertEquals(4,                           bat.getValueAt(3));
        assertEquals(5,                           bat.getValueAt(4));
@@ -1002,7 +1002,7 @@
        assertEquals(8,                           bat.getValueAt(7));
        assertEquals(9,                           bat.getValueAt(8));
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); // End of Normal
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Props
+       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
        
        normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
@@ -1010,14 +1010,14 @@
        assertEquals(4096, ((DocumentNode)normal).getProperty().getSize());
        
        
-       // Make longer, take 1 block after the properties too
+       // Make longer, take 1 block at the end
        normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
        nout = new NDocumentOutputStream(normal);
        nout.write(main4106);
        nout.close();
 
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
        assertEquals(3,                           bat.getValueAt(2));
        assertEquals(4,                           bat.getValueAt(3));
        assertEquals(5,                           bat.getValueAt(4));
@@ -1025,9 +1025,9 @@
        assertEquals(7,                           bat.getValueAt(6));
        assertEquals(8,                           bat.getValueAt(7));
        assertEquals(9,                           bat.getValueAt(8));
-       assertEquals(11,                          bat.getValueAt(9));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Props
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11)); // Normal
+       assertEquals(10,                          bat.getValueAt(9));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Normal
+       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
        
        normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
@@ -1042,8 +1042,8 @@
        nout.write(mini);
        nout.close();
        
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
@@ -1052,7 +1052,7 @@
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(7));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(8));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(9));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Props
+       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
        
@@ -1067,8 +1067,8 @@
        nout.close();
        
        // Will keep the mini stream, now empty
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
        assertEquals(5,                           bat.getValueAt(4));
@@ -1076,10 +1076,10 @@
        assertEquals(7,                           bat.getValueAt(6));
        assertEquals(8,                           bat.getValueAt(7));
        assertEquals(9,                           bat.getValueAt(8));
-       assertEquals(11,                          bat.getValueAt(9));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Props
-       assertEquals(12,                          bat.getValueAt(11));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(12));
+       assertEquals(10,                          bat.getValueAt(9));
+       assertEquals(11,                          bat.getValueAt(10));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
+       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
        
        normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
@@ -1091,8 +1091,8 @@
        fs = writeOutAndReadBack(fs);
        bat = fs.getBATBlockAndIndex(0).getBlock();
        
-       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(1));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
        assertEquals(5,                           bat.getValueAt(4));
@@ -1100,10 +1100,10 @@
        assertEquals(7,                           bat.getValueAt(6));
        assertEquals(8,                           bat.getValueAt(7));
        assertEquals(9,                           bat.getValueAt(8));
-       assertEquals(11,                          bat.getValueAt(9));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Props
-       assertEquals(12,                          bat.getValueAt(11));
-       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(12));
+       assertEquals(10,                          bat.getValueAt(9));
+       assertEquals(11,                          bat.getValueAt(10));
+       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
+       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
        
        normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java
index de5824e..2655b44 100644
--- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java
+++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java
@@ -22,7 +22,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.util.Iterator;
 
 import junit.framework.TestCase;
 
@@ -36,13 +35,10 @@
 import org.apache.poi.poifs.storage.RawDataBlockList;
 
 /**
- * Tests for POIFSFileSystem
- *
- * @author Josh Micich
+ * Tests for the older OPOIFS-based POIFSFileSystem
  */
 public final class TestPOIFSFileSystem extends TestCase {
    private POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
-   
 
 	/**
 	 * Mock exception used to ensure correct error handling
@@ -108,7 +104,7 @@
 		// Normal case - read until EOF and close
 		testIS = new TestIS(openSampleStream("13224.xls"), -1);
 		try {
-			new POIFSFileSystem(testIS);
+			new OPOIFSFileSystem(testIS);
 		} catch (IOException e) {
 			throw new RuntimeException(e);
 		}
@@ -117,7 +113,7 @@
 		// intended to crash after reading 10000 bytes
 		testIS = new TestIS(openSampleStream("13224.xls"), 10000);
 		try {
-			new POIFSFileSystem(testIS);
+			new OPOIFSFileSystem(testIS);
 			fail("ex should have been thrown");
 		} catch (IOException e) {
 			throw new RuntimeException(e);
@@ -145,7 +141,7 @@
 
 		for(int i=0; i<files.length; i++) {
 			// Open the file up
-			POIFSFileSystem fs = new POIFSFileSystem(
+			OPOIFSFileSystem fs = new OPOIFSFileSystem(
 			    _samples.openResourceAsStream(files[i])
 			);
 
@@ -167,7 +163,7 @@
         try {
             InputStream stream = _samples.openResourceAsStream("ReferencesInvalidSectors.mpp");
             try {
-                new POIFSFileSystem(stream);
+                new OPOIFSFileSystem(stream);
                 fail("File is corrupt and shouldn't have been opened");
             } finally {
                 stream.close();
@@ -186,7 +182,7 @@
 	 */
 	public void testBATandXBAT() throws Exception {
 	   byte[] hugeStream = new byte[8*1024*1024];
-	   POIFSFileSystem fs = new POIFSFileSystem();
+	   OPOIFSFileSystem fs = new OPOIFSFileSystem();
 	   fs.getRoot().createDocument(
 	         "BIG", new ByteArrayInputStream(hugeStream)
 	   );
@@ -230,7 +226,7 @@
       
 	   // Now load it and check
 	   fs = null;
-	   fs = new POIFSFileSystem(
+	   fs = new OPOIFSFileSystem(
 	         new ByteArrayInputStream(fsData)
 	   );
 	   
@@ -264,7 +260,7 @@
             assertEquals(15, data_blocks.blockCount());
 
             // Now try and open properly
-            POIFSFileSystem fs = new POIFSFileSystem(
+            OPOIFSFileSystem fs = new OPOIFSFileSystem(
                     _samples.openResourceAsStream("BlockSize4096.zvi"));
             assertTrue(fs.getRoot().getEntryCount() > 3);
 
@@ -272,7 +268,7 @@
             checkAllDirectoryContents(fs.getRoot());
 
             // Finally, check we can do a similar 512byte one too
-            fs = new POIFSFileSystem(
+            fs = new OPOIFSFileSystem(
                     _samples.openResourceAsStream("BlockSize512.zvi"));
             assertTrue(fs.getRoot().getEntryCount() > 3);
             checkAllDirectoryContents(fs.getRoot());
@@ -297,43 +293,6 @@
 	      }
 	   }
 	}
-	
-	/**
-	 * Test that we can open files that come via Lotus notes.
-	 * These have a top level directory without a name....
-	 */
-	public void testNotesOLE2Files() throws Exception {
-      POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
-      
-      // Open the file up
-      POIFSFileSystem fs = new POIFSFileSystem(
-          _samples.openResourceAsStream("Notes.ole2")
-      );
-      
-      // Check the contents
-      assertEquals(1, fs.getRoot().getEntryCount());
-      
-      Entry entry = fs.getRoot().getEntries().next();
-      assertTrue(entry.isDirectoryEntry());
-      assertTrue(entry instanceof DirectoryEntry);
-      
-      // The directory lacks a name!
-      DirectoryEntry dir = (DirectoryEntry)entry;
-      assertEquals("", dir.getName());
-      
-      // Has two children
-      assertEquals(2, dir.getEntryCount());
-      
-      // Check them
-      Iterator<Entry> it = dir.getEntries();
-      entry = it.next();
-      assertEquals(true, entry.isDocumentEntry());
-      assertEquals("\u0001Ole10Native", entry.getName());
-      
-      entry = it.next();
-      assertEquals(true, entry.isDocumentEntry());
-      assertEquals("\u0001CompObj", entry.getName());
-	}
 
 	private static InputStream openSampleStream(String sampleFileName) {
 		return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java
index 3fc77b8..11c7070 100644
--- a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java
+++ b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java
@@ -26,6 +26,7 @@
 
 import junit.framework.TestCase;
 
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
 import org.apache.poi.poifs.common.POIFSConstants;
 
 /**
@@ -283,6 +284,59 @@
        );
     }
     
+    public void testUsedSectors() throws Exception {
+        POIFSBigBlockSize b512 = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
+        POIFSBigBlockSize b4096 = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS;
+        
+        // Try first with 512 block sizes, which can hold 128 entries
+        BATBlock block512 = BATBlock.createEmptyBATBlock(b512, false);
+        assertEquals(true, block512.hasFreeSectors());
+        assertEquals(0, block512.getUsedSectors(false));
+
+        // Allocate a few
+        block512.setValueAt(0, 42);
+        block512.setValueAt(10, 42);
+        block512.setValueAt(20, 42);
+        assertEquals(true, block512.hasFreeSectors());
+        assertEquals(3, block512.getUsedSectors(false));
+        
+        // Allocate all
+        for (int i=0; i<b512.getBATEntriesPerBlock(); i++) {
+            block512.setValueAt(i, 82);
+        }
+        // Check
+        assertEquals(false, block512.hasFreeSectors());
+        assertEquals(128, block512.getUsedSectors(false));
+        assertEquals(127, block512.getUsedSectors(true));
+        
+        // Release one
+        block512.setValueAt(10, POIFSConstants.UNUSED_BLOCK);
+        assertEquals(true, block512.hasFreeSectors());
+        assertEquals(127, block512.getUsedSectors(false));
+        assertEquals(126, block512.getUsedSectors(true));
+        
+        
+        // Now repeat with 4096 block sizes
+        BATBlock block4096 = BATBlock.createEmptyBATBlock(b4096, false);
+        assertEquals(true, block4096.hasFreeSectors());
+        assertEquals(0, block4096.getUsedSectors(false));
+        
+        block4096.setValueAt(0, 42);
+        block4096.setValueAt(10, 42);
+        block4096.setValueAt(20, 42);
+        assertEquals(true, block4096.hasFreeSectors());
+        assertEquals(3, block4096.getUsedSectors(false));
+        
+        // Allocate all
+        for (int i=0; i<b4096.getBATEntriesPerBlock(); i++) {
+            block4096.setValueAt(i, 82);
+        }
+        // Check
+        assertEquals(false, block4096.hasFreeSectors());
+        assertEquals(1024, block4096.getUsedSectors(false));
+        assertEquals(1023, block4096.getUsedSectors(true));
+    }
+    
     public void testGetBATBlockAndIndex() throws Exception {
        HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
        List<BATBlock> blocks = new ArrayList<BATBlock>();
diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java
index f10576a..9bb4f6a 100644
--- a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java
+++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java
@@ -25,7 +25,7 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.poifs.common.POIFSConstants;
-import org.apache.poi.poifs.filesystem.POIFSDocument;
+import org.apache.poi.poifs.filesystem.OPOIFSDocument;
 import org.apache.poi.poifs.property.PropertyTable;
 import org.apache.poi.poifs.property.RootProperty;
 
@@ -37,43 +37,43 @@
 public final class TestSmallBlockTableWriter extends TestCase {
 
     public void testWritingConstructor() throws IOException {
-        List<POIFSDocument> documents = new ArrayList<POIFSDocument>();
+        List<OPOIFSDocument> documents = new ArrayList<OPOIFSDocument>();
 
         documents.add(
-            new POIFSDocument(
+            new OPOIFSDocument(
                 "doc340", new ByteArrayInputStream(new byte[ 340 ])));
         documents.add(
-            new POIFSDocument(
+            new OPOIFSDocument(
                 "doc5000", new ByteArrayInputStream(new byte[ 5000 ])));
         documents
-            .add(new POIFSDocument("doc0",
+            .add(new OPOIFSDocument("doc0",
                                    new ByteArrayInputStream(new byte[ 0 ])));
         documents
-            .add(new POIFSDocument("doc1",
+            .add(new OPOIFSDocument("doc1",
                                    new ByteArrayInputStream(new byte[ 1 ])));
         documents
-            .add(new POIFSDocument("doc2",
+            .add(new OPOIFSDocument("doc2",
                                    new ByteArrayInputStream(new byte[ 2 ])));
         documents
-            .add(new POIFSDocument("doc3",
+            .add(new OPOIFSDocument("doc3",
                                    new ByteArrayInputStream(new byte[ 3 ])));
         documents
-            .add(new POIFSDocument("doc4",
+            .add(new OPOIFSDocument("doc4",
                                    new ByteArrayInputStream(new byte[ 4 ])));
         documents
-            .add(new POIFSDocument("doc5",
+            .add(new OPOIFSDocument("doc5",
                                    new ByteArrayInputStream(new byte[ 5 ])));
         documents
-            .add(new POIFSDocument("doc6",
+            .add(new OPOIFSDocument("doc6",
                                    new ByteArrayInputStream(new byte[ 6 ])));
         documents
-            .add(new POIFSDocument("doc7",
+            .add(new OPOIFSDocument("doc7",
                                    new ByteArrayInputStream(new byte[ 7 ])));
         documents
-            .add(new POIFSDocument("doc8",
+            .add(new OPOIFSDocument("doc8",
                                    new ByteArrayInputStream(new byte[ 8 ])));
         documents
-            .add(new POIFSDocument("doc9",
+            .add(new OPOIFSDocument("doc9",
                                    new ByteArrayInputStream(new byte[ 9 ])));
         
         HeaderBlock              header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS);
diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java
index b061483..31c4546 100644
--- a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java
+++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java
@@ -21,13 +21,12 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
-import org.apache.poi.poifs.common.POIFSConstants;
-
 import junit.framework.TestCase;
 
+import org.apache.poi.poifs.common.POIFSConstants;
+
 /**
  * Class to test SmallDocumentBlock functionality
  *
@@ -53,7 +52,7 @@
         throws IOException
     {
         ByteArrayInputStream stream    = new ByteArrayInputStream(_testdata);
-        List                 documents = new ArrayList();
+        List<DocumentBlock> documents  = new ArrayList<DocumentBlock>();
 
         while (true)
         {
@@ -66,9 +65,8 @@
             }
         }
         SmallDocumentBlock[] results =
-            SmallDocumentBlock
-                .convert(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,( BlockWritable [] ) documents
-                    .toArray(new DocumentBlock[ 0 ]), _testdata_size);
+            SmallDocumentBlock.convert(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,
+                          documents.toArray(new DocumentBlock[ 0 ]), _testdata_size);
 
         assertEquals("checking correct result size: ",
                      (_testdata_size + 63) / 64, results.length);
@@ -142,20 +140,20 @@
     {
         for (int j = 0; j <= 8; j++)
         {
-            List foo = new ArrayList();
+            List<SmallDocumentBlock> blocks = new ArrayList<SmallDocumentBlock>();
 
             for (int k = 0; k < j; k++)
             {
-                foo.add(new Object());
+                blocks.add(new SmallDocumentBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS));
             }
-            int result = SmallDocumentBlock.fill(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,foo);
+            int result = SmallDocumentBlock.fill(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blocks);
 
             assertEquals("correct big block count: ", (j + 7) / 8, result);
             assertEquals("correct small block count: ", 8 * result,
-                         foo.size());
-            for (int m = j; m < foo.size(); m++)
+                         blocks.size());
+            for (int m = j; m < blocks.size(); m++)
             {
-                BlockWritable         block  = ( BlockWritable ) foo.get(m);
+                BlockWritable         block  = blocks.get(m);
                 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 
                 block.writeBlocks(stream);
@@ -208,13 +206,12 @@
         {
             new RawDataBlock(new ByteArrayInputStream(data))
         };
-        List           output = SmallDocumentBlock.extract(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,blocks);
-        Iterator       iter   = output.iterator();
+        List<SmallDocumentBlock> output = SmallDocumentBlock.extract(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,blocks);
 
         offset = 0;
-        while (iter.hasNext())
+        for (SmallDocumentBlock block : output)
         {
-            byte[] out_data = (( SmallDocumentBlock ) iter.next()).getData();
+            byte[] out_data = block.getData();
 
             assertEquals("testing block at offset " + offset, 64,
                          out_data.length);
diff --git a/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java b/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java
index 13581c8..617f7b0 100644
--- a/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java
+++ b/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java
@@ -516,6 +516,7 @@
 		ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )");
 		ps.println("");
 		try {
+		    // can't use ZipHelper here, because its in a different module
 			ZipFile zf = new ZipFile(effDocFile);
 			InputStream is = zf.getInputStream(zf.getEntry("content.xml"));
 			extractFunctionData(new FunctionDataCollector(ps), is);
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunction.java b/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunction.java
new file mode 100644
index 0000000..628df03
--- /dev/null
+++ b/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunction.java
@@ -0,0 +1,105 @@
+/* ====================================================================

+   Licensed to the Apache Software Foundation (ASF) under one or more

+   contributor license agreements.  See the NOTICE file distributed with

+   this work for additional information regarding copyright ownership.

+   The ASF licenses this file to You under the Apache License, Version 2.0

+   (the "License"); you may not use this file except in compliance with

+   the License.  You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

+==================================================================== */

+

+package org.apache.poi.ss.formula.functions;

+

+import java.io.IOException;

+

+import junit.framework.TestCase;

+import org.apache.poi.hssf.usermodel.HSSFWorkbook;

+import org.apache.poi.ss.usermodel.Cell;

+import org.apache.poi.ss.usermodel.CellValue;

+import org.apache.poi.ss.usermodel.FormulaEvaluator;

+import org.apache.poi.ss.usermodel.Row;

+import org.apache.poi.ss.usermodel.Sheet;

+import org.apache.poi.ss.usermodel.Workbook;

+import org.apache.poi.ss.util.CellReference;

+

+/**

+ * LogicalFunction unit tests.

+ */

+public class TestLogicalFunction extends TestCase {

+

+    private FormulaEvaluator evaluator;

+    private Row row3;

+    private Cell cell1;

+    private Cell cell2;

+

+    @Override

+    public void setUp() throws IOException {

+        Workbook wb = new HSSFWorkbook();

+        try {

+            buildWorkbook(wb);

+        } finally {

+            wb.close();

+        }

+    }

+

+    private void buildWorkbook(Workbook wb) {

+        Sheet sh = wb.createSheet();

+        Row row1 = sh.createRow(0);

+        Row row2 = sh.createRow(1);

+        row3 = sh.createRow(2);

+

+        row1.createCell(0, Cell.CELL_TYPE_NUMERIC);

+        row1.createCell(1, Cell.CELL_TYPE_NUMERIC);

+

+        row2.createCell(0, Cell.CELL_TYPE_NUMERIC);

+        row2.createCell(1, Cell.CELL_TYPE_NUMERIC);

+

+        row3.createCell(0);

+        row3.createCell(1);

+

+        CellReference a1 = new CellReference("A1");

+        CellReference a2 = new CellReference("A2");

+        CellReference b1 = new CellReference("B1");

+        CellReference b2 = new CellReference("B2");

+

+        sh.getRow(a1.getRow()).getCell(a1.getCol()).setCellValue(35);

+        sh.getRow(a2.getRow()).getCell(a2.getCol()).setCellValue(0);

+        sh.getRow(b1.getRow()).getCell(b1.getCol()).setCellFormula("A1/A2");

+        sh.getRow(b2.getRow()).getCell(b2.getCol()).setCellFormula("NA()");

+

+        evaluator = wb.getCreationHelper().createFormulaEvaluator();

+    }

+

+    public void testIsErr() {

+        cell1 = row3.createCell(0);

+        cell1.setCellFormula("ISERR(B1)"); // produces #DIV/0!

+        cell2 = row3.createCell(1);

+        cell2.setCellFormula("ISERR(B2)"); // produces #N/A

+

+        CellValue cell1Value = evaluator.evaluate(cell1);

+        CellValue cell2Value = evaluator.evaluate(cell2);

+

+        assertEquals(true, cell1Value.getBooleanValue());

+        assertEquals(false, cell2Value.getBooleanValue());

+    }

+

+    public void testIsError() {

+        cell1 = row3.createCell(0);

+        cell1.setCellFormula("ISERROR(B1)"); // produces #DIV/0!

+        cell2 = row3.createCell(1);

+        cell2.setCellFormula("ISERROR(B2)"); // produces #N/A

+

+        CellValue cell1Value = evaluator.evaluate(cell1);

+        CellValue cell2Value = evaluator.evaluate(cell2);

+

+        assertEquals(true, cell1Value.getBooleanValue());

+        assertEquals(true, cell2Value.getBooleanValue());

+    }

+}

diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestSumif.java b/src/testcases/org/apache/poi/ss/formula/functions/TestSumif.java
index 6cee5ea..c761d22 100644
--- a/src/testcases/org/apache/poi/ss/formula/functions/TestSumif.java
+++ b/src/testcases/org/apache/poi/ss/formula/functions/TestSumif.java
@@ -21,6 +21,8 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.ss.formula.eval.AreaEval;
+import org.apache.poi.ss.formula.eval.BlankEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.NumericValueEval;
 import org.apache.poi.ss.formula.eval.StringEval;
@@ -107,4 +109,11 @@
 
 		confirmDouble(60, ve);
 	}
+
+	public void testEvaluateException() {
+	    assertEquals(ErrorEval.VALUE_INVALID, invokeSumif(-1, -1, BlankEval.instance, new NumberEval(30.0)));
+        assertEquals(ErrorEval.VALUE_INVALID, invokeSumif(-1, -1, BlankEval.instance, new NumberEval(30.0), new NumberEval(30.0)));
+        assertEquals(ErrorEval.VALUE_INVALID, invokeSumif(-1, -1, new NumberEval(30.0), BlankEval.instance, new NumberEval(30.0)));
+        assertEquals(ErrorEval.VALUE_INVALID, invokeSumif(-1, -1, new NumberEval(30.0), new NumberEval(30.0), BlankEval.instance));
+	}
 }
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestSumifs.java b/src/testcases/org/apache/poi/ss/formula/functions/TestSumifs.java
index 386b521..3f611cb 100644
--- a/src/testcases/org/apache/poi/ss/formula/functions/TestSumifs.java
+++ b/src/testcases/org/apache/poi/ss/formula/functions/TestSumifs.java
@@ -21,6 +21,7 @@
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
+
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.ss.formula.OperationEvaluationContext;
@@ -264,4 +265,84 @@
         assertEquals(625000., ex5cell.getNumericCellValue());
 
     }
+    
+    public void testBug56655() {
+        ValueEval[] a2a9 = new ValueEval[] {
+                new NumberEval(5),
+                new NumberEval(4),
+                new NumberEval(15),
+                new NumberEval(3),
+                new NumberEval(22),
+                new NumberEval(12),
+                new NumberEval(10),
+                new NumberEval(33)
+        };
+
+        ValueEval[] args = new ValueEval[]{
+                EvalFactory.createAreaEval("A2:A9", a2a9),
+                ErrorEval.VALUE_INVALID,
+                new StringEval("A*"),
+        };
+        
+        ValueEval result = invokeSumifs(args, EC);
+        assertTrue("Expect to have an error when an input is an invalid value, but had: " + result.getClass(), result instanceof ErrorEval);
+
+        args = new ValueEval[]{
+                EvalFactory.createAreaEval("A2:A9", a2a9),
+                EvalFactory.createAreaEval("A2:A9", a2a9),
+                ErrorEval.VALUE_INVALID,
+        };
+        
+        result = invokeSumifs(args, EC);
+        assertTrue("Expect to have an error when an input is an invalid value, but had: " + result.getClass(), result instanceof ErrorEval);
+    }
+
+    public void testBug56655b() {
+/*
+        setCellFormula(sheet, 0, 0, "B1*C1");
+        sheet.getRow(0).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 1, 0, "B1*C1");
+        sheet.getRow(1).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 0, 3, "SUMIFS(A:A,A:A,A2)");
+ */
+    	ValueEval[] a0a1 = new ValueEval[] {
+                NumberEval.ZERO,
+                NumberEval.ZERO
+        };
+
+        ValueEval[] args = new ValueEval[]{
+                EvalFactory.createAreaEval("A0:A1", a0a1),
+                EvalFactory.createAreaEval("A0:A1", a0a1),
+                ErrorEval.VALUE_INVALID
+        };
+        
+        ValueEval result = invokeSumifs(args, EC);
+        assertTrue("Expect to have an error when an input is an invalid value, but had: " + result.getClass(), result instanceof ErrorEval);
+        assertEquals(ErrorEval.VALUE_INVALID, result);
+    }
+
+
+    public void testBug56655c() {
+/*
+        setCellFormula(sheet, 0, 0, "B1*C1");
+        sheet.getRow(0).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 1, 0, "B1*C1");
+        sheet.getRow(1).createCell(1).setCellValue("A");
+        setCellFormula(sheet, 0, 3, "SUMIFS(A:A,A:A,A2)");
+ */
+        ValueEval[] a0a1 = new ValueEval[] {
+                NumberEval.ZERO,
+                NumberEval.ZERO
+        };
+
+        ValueEval[] args = new ValueEval[]{
+                EvalFactory.createAreaEval("A0:A1", a0a1),
+                EvalFactory.createAreaEval("A0:A1", a0a1),
+                ErrorEval.NAME_INVALID
+        };
+        
+        ValueEval result = invokeSumifs(args, EC);
+        assertTrue("Expect to have an error when an input is an invalid value, but had: " + result.getClass(), result instanceof ErrorEval);
+        assertEquals(ErrorEval.NAME_INVALID, result);
+    }
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java
index fe11df6..69cf052 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java
@@ -18,9 +18,12 @@
 package org.apache.poi.ss.usermodel;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -29,6 +32,9 @@
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.SheetUtil;
+import org.junit.Assume;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -120,7 +126,7 @@
      * Merged regions were being removed from the parent in cloned sheets
      */
     @Test
-    public final void bug22720() {
+    public void bug22720() {
        Workbook workBook = _testDataProvider.createWorkbook();
        workBook.createSheet("TEST");
        Sheet template = workBook.getSheetAt(0);
@@ -244,7 +250,7 @@
     }
 
     @Test
-    public final void bug18800() {
+    public void bug18800() {
        Workbook book = _testDataProvider.createWorkbook();
        book.createSheet("TEST");
        Sheet sheet = book.cloneSheet(0);
@@ -273,7 +279,7 @@
     }
 
     @Test
-    public final void bug43093() {
+    public void bug43093() {
         Workbook xlw = _testDataProvider.createWorkbook();
 
         addNewSheetWithCellsA1toD4(xlw, 1);
@@ -293,7 +299,7 @@
     }
 
     @Test
-    public final void bug46729_testMaxFunctionArguments(){
+    public void bug46729_testMaxFunctionArguments(){
         String[] func = {"COUNT", "AVERAGE", "MAX", "MIN", "OR", "SUBTOTAL", "SKEW"};
 
         SpreadsheetVersion ssVersion = _testDataProvider.getSpreadsheetVersion();
@@ -332,7 +338,7 @@
     }
 
     @Test
-    public final void bug506819_testAutoSize() {
+    public final void bug50681_testAutoSize() {
         Workbook wb = _testDataProvider.createWorkbook();
         BaseTestSheetAutosizeColumn.fixFonts(wb);
         Sheet sheet = wb.createSheet("Sheet1");
@@ -348,7 +354,26 @@
 
         cell0.setCellValue(longValue);
 
+        // autoSize will fail if required fonts are not installed, skip this test then
+        Font font = wb.getFontAt(cell0.getCellStyle().getFontIndex());
+        Assume.assumeTrue("Cannot verify auoSizeColumn() because the necessary Fonts are not installed on this machine: " + font, 
+                SheetUtil.canComputeColumnWidht(font));
+        
+        assertEquals("Expecting no indentation in this test",
+                0, cell0.getCellStyle().getIndention());
+
+        double width = SheetUtil.getColumnWidth(sheet, 0, false);
+        assertTrue("Expected to have column width > 0 BEFORE auto-size, but had " + width, width > 0);
+        width = SheetUtil.getCellWidth(cell0, 8, null, false);
+        assertTrue("Expected to have cell width > 0 BEFORE auto-size, but had " + width, width > 0);
+
         sheet.autoSizeColumn(0);
+        
+        width = SheetUtil.getColumnWidth(sheet, 0, false);
+        assertTrue("Expected to have column width > 0 AFTER auto-size, but had " + width, width > 0);
+        width = SheetUtil.getCellWidth(cell0, 8, null, false);
+        assertTrue("Expected to have cell width > 0 AFTER auto-size, but had " + width, width > 0);
+        
         assertEquals(255*256, sheet.getColumnWidth(0)); // maximum column width is 255 characters
         sheet.setColumnWidth(0, sheet.getColumnWidth(0)); // Bug 506819 reports exception at this point
     }
@@ -416,16 +441,16 @@
         Workbook wb = _testDataProvider.createWorkbook();
         Sheet sheet = wb.createSheet("My sheet");
 
-        Row row = sheet.createRow( 0 );
-        Cell cell = row.createCell( 0 );
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
         cell.setCellFormula(hyperlinkF);
         
         assertEquals(hyperlinkF, cell.getCellFormula());
 
         wb = _testDataProvider.writeOutAndReadBack(wb);
         sheet = wb.getSheet("My Sheet");
-        row = sheet.getRow( 0 );
-        cell = row.getCell( 0 );
+        row = sheet.getRow(0);
+        cell = row.getCell(0);
         
         assertEquals(hyperlinkF, cell.getCellFormula());
     }
@@ -531,7 +556,7 @@
         assertAlmostEquals(1950, s.getColumnWidth(10), fontAccuracy);
         assertAlmostEquals(2225, s.getColumnWidth(11), fontAccuracy);
     }
-    
+
     /**
      * =ISNUMBER(SEARCH("AM",A1)) evaluation 
      */
@@ -637,7 +662,7 @@
         // Next up, SEARCH on its own
         cf.setCellFormula("SEARCH(\"am\", A1)");
         cf = evaluateCell(wb, cf);
-        assertEquals(ErrorConstants.ERROR_VALUE, cf.getErrorCellValue());
+        assertEquals(FormulaError.VALUE.getCode(), cf.getErrorCellValue());
         
         cf.setCellFormula("SEARCH(\"am\", B1)");
         cf = evaluateCell(wb, cf);
@@ -645,11 +670,11 @@
         
         cf.setCellFormula("SEARCH(\"am\", C1)");
         cf = evaluateCell(wb, cf);
-        assertEquals(ErrorConstants.ERROR_VALUE, cf.getErrorCellValue());
+        assertEquals(FormulaError.VALUE.getCode(), cf.getErrorCellValue());
         
         cf.setCellFormula("SEARCH(\"am\", D1)");
         cf = evaluateCell(wb, cf);
-        assertEquals(ErrorConstants.ERROR_VALUE, cf.getErrorCellValue());
+        assertEquals(FormulaError.VALUE.getCode(), cf.getErrorCellValue());
         
         
         // Finally, bring it all together
@@ -688,7 +713,8 @@
      * TODO Fix this to evaluate for XSSF
      * TODO Fix this to work at all for HSSF
      */
-//    @Test
+    @Ignore("Fix this to evaluate for XSSF, Fix this to work at all for HSSF")
+    @Test
     public void bug46670() throws Exception {
         Workbook wb = _testDataProvider.createWorkbook();
         Sheet s = wb.createSheet();
@@ -727,7 +753,7 @@
         assertEquals(refHttp,  c2.getCellFormula());
 
         
-        // Try to evalutate, without giving a way to get at the other file
+        // Try to evaluate, without giving a way to get at the other file
         try {
             evaluateCell(wb, c1);
             fail("Shouldn't be able to evaluate without the other file");
@@ -757,4 +783,287 @@
         assertEquals(otherCellText, c1.getStringCellValue());
         assertEquals(otherCellText, c2.getStringCellValue());
     }
+
+    @Test
+    public void test56574OverwriteExistingRow() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet();
+        
+        { // create the Formula-Cell
+            Row row = sheet.createRow(0);
+            Cell cell = row.createCell(0);
+            cell.setCellFormula("A2");
+        }
+        
+        { // check that it is there now
+            Row row = sheet.getRow(0);
+            
+           /* CTCell[] cArray = ((XSSFRow)row).getCTRow().getCArray();
+            assertEquals(1, cArray.length);*/
+
+            Cell cell = row.getCell(0);
+            assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType());
+        }
+        
+        { // overwrite the row
+            Row row = sheet.createRow(0);
+            assertNotNull(row);
+        }
+        
+        { // creating a row in place of another should remove the existing data,
+            // check that the cell is gone now
+            Row row = sheet.getRow(0);
+            
+            /*CTCell[] cArray = ((XSSFRow)row).getCTRow().getCArray();
+            assertEquals(0, cArray.length);*/
+
+            Cell cell = row.getCell(0);
+            assertNull(cell);
+        }
+        
+        // the calculation chain in XSSF is empty in a newly created workbook, so we cannot check if it is correctly updated
+        /*assertNull(((XSSFWorkbook)wb).getCalculationChain());
+        assertNotNull(((XSSFWorkbook)wb).getCalculationChain().getCTCalcChain());
+        assertNotNull(((XSSFWorkbook)wb).getCalculationChain().getCTCalcChain().getCArray());
+        assertEquals(0, ((XSSFWorkbook)wb).getCalculationChain().getCTCalcChain().getCArray().length);*/
+
+        wb.close();
+    }
+
+    /**
+     * With HSSF, if you create a font, don't change it, and
+     *  create a 2nd, you really do get two fonts that you 
+     *  can alter as and when you want.
+     * With XSSF, that wasn't the case, but this verfies
+     *  that it now is again
+     */
+    @Test
+    public void bug48718() throws Exception {
+        Workbook wb = _testDataProvider.createWorkbook();
+        int startingFonts = wb instanceof HSSFWorkbook ? 4 : 1;
+
+        assertEquals(startingFonts, wb.getNumberOfFonts());
+
+        // Get a font, and slightly change it
+        Font a = wb.createFont();
+        assertEquals(startingFonts+1, wb.getNumberOfFonts());
+        a.setFontHeightInPoints((short)23);
+        assertEquals(startingFonts+1, wb.getNumberOfFonts());
+
+        // Get two more, unchanged
+        /*Font b =*/ wb.createFont();
+        assertEquals(startingFonts+2, wb.getNumberOfFonts());
+        /*Font c =*/ wb.createFont();
+        assertEquals(startingFonts+3, wb.getNumberOfFonts());
+    }
+
+    @Test
+    public void bug57430() throws Exception {
+        Workbook wb = _testDataProvider.createWorkbook();
+        try {
+            wb.createSheet("Sheet1");
+
+            Name name1 = wb.createName();
+            name1.setNameName("FMLA");
+            name1.setRefersToFormula("Sheet1!$B$3");
+        } finally {
+            wb.close();
+        }
+    }
+
+    @Test
+    public void bug56981() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        CellStyle vertTop = wb.createCellStyle();
+        vertTop.setVerticalAlignment(CellStyle.VERTICAL_TOP);
+        CellStyle vertBottom = wb.createCellStyle();
+        vertBottom.setVerticalAlignment(CellStyle.VERTICAL_BOTTOM);
+        Sheet sheet = wb.createSheet("Sheet 1");
+        Row row = sheet.createRow(0);
+        Cell top = row.createCell(0);
+        Cell bottom = row.createCell(1);
+        top.setCellValue("Top");
+        top.setCellStyle(vertTop); // comment this out to get all bottom-aligned
+                                   // cells
+        bottom.setCellValue("Bottom");
+        bottom.setCellStyle(vertBottom);
+        row.setHeightInPoints(85.75f); // make it obvious
+
+        /*FileOutputStream out = new FileOutputStream("c:\\temp\\56981.xlsx");
+        try {
+            wb.write(out);
+        } finally {
+            out.close();
+        }*/
+        
+        wb.close();
+    }
+
+    @Test
+    public void test57973() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+
+        CreationHelper factory = wb.getCreationHelper();
+
+        Sheet sheet = wb.createSheet();
+        Drawing drawing = sheet.createDrawingPatriarch();
+        ClientAnchor anchor = factory.createClientAnchor();
+        
+        Cell cell0 = sheet.createRow(0).createCell(0);
+        cell0.setCellValue("Cell0");
+
+        Comment comment0 = drawing.createCellComment(anchor);
+        RichTextString str0 = factory.createRichTextString("Hello, World1!");
+        comment0.setString(str0);
+        comment0.setAuthor("Apache POI");
+        cell0.setCellComment(comment0);
+        
+        anchor = factory.createClientAnchor();
+        anchor.setCol1(1);
+        anchor.setCol2(1);
+        anchor.setRow1(1);
+        anchor.setRow2(1);
+        Cell cell1 = sheet.createRow(3).createCell(5);
+        cell1.setCellValue("F4");
+        Comment comment1 = drawing.createCellComment(anchor);
+        RichTextString str1 = factory.createRichTextString("Hello, World2!");
+        comment1.setString(str1);
+        comment1.setAuthor("Apache POI");
+        cell1.setCellComment(comment1);
+
+        Cell cell2 = sheet.createRow(2).createCell(2);
+        cell2.setCellValue("C3");
+
+        anchor = factory.createClientAnchor();
+        anchor.setCol1(2);
+        anchor.setCol2(2);
+        anchor.setRow1(2);
+        anchor.setRow2(2);
+
+        Comment comment2 = drawing.createCellComment(anchor);
+        RichTextString str2 = factory.createRichTextString("XSSF can set cell comments");
+        //apply custom font to the text in the comment
+        Font font = wb.createFont();
+        font.setFontName("Arial");
+        font.setFontHeightInPoints((short)14);
+        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
+        font.setColor(IndexedColors.RED.getIndex());
+        str2.applyFont(font);
+
+        comment2.setString(str2);
+        comment2.setAuthor("Apache POI");
+        comment2.setColumn(2);
+        comment2.setRow(2);
+
+        /*OutputStream out = new FileOutputStream("C:\\temp\\57973.xlsx");
+        try {
+            wb.write(out);
+        } finally {
+            out.close();
+        }*/
+        
+        wb.close();
+    }
+
+    /**
+     * Ensures that XSSF and HSSF agree with each other,
+     *  and with the docs on when fetching the wrong
+     *  kind of value from a Formula cell
+     */
+    @Test
+    public void bug47815() {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet s = wb.createSheet();
+        Row r = s.createRow(0);
+
+        // Setup
+        Cell cn = r.createCell(0, Cell.CELL_TYPE_NUMERIC);
+        cn.setCellValue(1.2);
+        Cell cs = r.createCell(1, Cell.CELL_TYPE_STRING);
+        cs.setCellValue("Testing");
+
+        Cell cfn = r.createCell(2, Cell.CELL_TYPE_FORMULA);
+        cfn.setCellFormula("A1");  
+        Cell cfs = r.createCell(3, Cell.CELL_TYPE_FORMULA);
+        cfs.setCellFormula("B1");
+
+        FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
+        assertEquals(Cell.CELL_TYPE_NUMERIC, fe.evaluate(cfn).getCellType());
+        assertEquals(Cell.CELL_TYPE_STRING, fe.evaluate(cfs).getCellType());
+        fe.evaluateFormulaCell(cfn);
+        fe.evaluateFormulaCell(cfs);
+
+        // Now test
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cn.getCellType());
+        assertEquals(Cell.CELL_TYPE_STRING, cs.getCellType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, cfn.getCellType());
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cfn.getCachedFormulaResultType());
+        assertEquals(Cell.CELL_TYPE_FORMULA, cfs.getCellType());
+        assertEquals(Cell.CELL_TYPE_STRING, cfs.getCachedFormulaResultType());
+
+        // Different ways of retrieving
+        assertEquals(1.2, cn.getNumericCellValue(), 0);
+        try {
+            cn.getRichStringCellValue();
+            fail();
+        } catch(IllegalStateException e) {}
+
+        assertEquals("Testing", cs.getStringCellValue());
+        try {
+            cs.getNumericCellValue();
+            fail();
+        } catch(IllegalStateException e) {}
+
+        assertEquals(1.2, cfn.getNumericCellValue(), 0);
+        try {
+            cfn.getRichStringCellValue();
+            fail();
+        } catch(IllegalStateException e) {}
+
+        assertEquals("Testing", cfs.getStringCellValue());
+        try {
+            cfs.getNumericCellValue();
+            fail();
+        } catch(IllegalStateException e) {}
+    }
+    
+    @Test
+    public void test58113() {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet( "Test" );
+
+        Row row = sheet.createRow(0);
+
+        Cell cell = row.createCell(0);
+        // verify that null-values can be set, this was possible up to 3.11, but broken in 3.12 
+        cell.setCellValue((String)null);
+        String value = cell.getStringCellValue();
+        assertTrue("HSSF will currently return empty string, XSSF/SXSSF will return null, but had: " + value,
+                value == null || value.length() == 0);
+        
+        cell = row.createCell(1);
+        // also verify that setting formulas to null works  
+        cell.setCellType(Cell.CELL_TYPE_FORMULA);
+        cell.setCellValue((String)null);
+        
+        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+
+        value = cell.getStringCellValue();
+        assertTrue("HSSF will currently return empty string, XSSF/SXSSF will return null, but had: " + value,
+                value == null || value.length() == 0);
+        
+        // set some value
+        cell.setCellType(Cell.CELL_TYPE_STRING);
+        cell.setCellValue("somevalue");
+
+        value = cell.getStringCellValue();
+        assertTrue("can set value afterwards: " + value,
+                value.equals("somevalue"));
+
+        // verify that the null-value is actually set even if there was some value in the cell before  
+        cell.setCellValue((String)null);
+        value = cell.getStringCellValue();
+        assertTrue("HSSF will currently return empty string, XSSF/SXSSF will return null, but had: " + value,
+                value == null || value.length() == 0);
+    }
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
index 35e95ab..533a973 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java
@@ -25,6 +25,7 @@
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.ITestDataProvider;
+import org.apache.poi.ss.SpreadsheetVersion;
 
 /**
  * Common superclass for testing implementations of
@@ -695,4 +696,75 @@
         
         wb.close();
     }
+
+	public void test57008() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+		Sheet sheet = wb.createSheet();
+		
+		Row row0 = sheet.createRow(0);
+		Cell cell0 = row0.createCell(0);
+		cell0.setCellValue("row 0, cell 0 _x0046_ without changes");
+		
+		Cell cell1 = row0.createCell(1);
+		cell1.setCellValue("row 0, cell 1 _x005fx0046_ with changes");
+		
+		Cell cell2 = row0.createCell(2);
+		cell2.setCellValue("hgh_x0041_**_x0100_*_x0101_*_x0190_*_x0200_*_x0300_*_x0427_*");
+
+		checkUnicodeValues(wb);
+		
+//		String fname = "/tmp/Test_xNNNN_inCell" + (wb instanceof HSSFWorkbook ? ".xls" : ".xlsx");
+//		FileOutputStream out = new FileOutputStream(fname);
+//		try {
+//			wb.write(out);
+//		} finally {
+//			out.close();
+//		}
+		
+		Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb);
+		checkUnicodeValues(wbBack);
+	}
+
+	private void checkUnicodeValues(Workbook wb) {
+		assertEquals((wb instanceof HSSFWorkbook ? "row 0, cell 0 _x0046_ without changes" : "row 0, cell 0 F without changes"), 
+				wb.getSheetAt(0).getRow(0).getCell(0).toString());
+		assertEquals((wb instanceof HSSFWorkbook ? "row 0, cell 1 _x005fx0046_ with changes" : "row 0, cell 1 _x005fx0046_ with changes"), 
+				wb.getSheetAt(0).getRow(0).getCell(1).toString());
+		assertEquals((wb instanceof HSSFWorkbook ? "hgh_x0041_**_x0100_*_x0101_*_x0190_*_x0200_*_x0300_*_x0427_*" : "hghA**\u0100*\u0101*\u0190*\u0200*\u0300*\u0427*"), 
+				wb.getSheetAt(0).getRow(0).getCell(2).toString());
+	}
+
+	/**
+	 *  The maximum length of cell contents (text) is 32,767 characters.
+	 * @throws IOException 
+	 */
+	public void testMaxTextLength() throws IOException{
+		Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet();
+		Cell cell = sheet.createRow(0).createCell(0);
+
+		int maxlen = wb instanceof HSSFWorkbook ? 
+				SpreadsheetVersion.EXCEL97.getMaxTextLength()
+				: SpreadsheetVersion.EXCEL2007.getMaxTextLength();
+		assertEquals(32767, maxlen);
+
+		StringBuffer b = new StringBuffer() ;
+
+		// 32767 is okay
+		for( int i = 0 ; i < maxlen ; i++ )
+		{
+			b.append( "X" ) ;
+		}
+		cell.setCellValue(b.toString());
+
+		b.append("X");
+		// 32768 produces an invalid XLS file
+		try {
+			cell.setCellValue(b.toString());
+			fail("Expected exception");
+		} catch (IllegalArgumentException e){
+			assertEquals("The maximum length of cell contents (text) is 32,767 characters", e.getMessage());
+		}
+		wb.close();
+	}
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
index b6e6ca9..b8eeb20 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
@@ -20,12 +20,16 @@
 package org.apache.poi.ss.usermodel;

 

 import junit.framework.TestCase;

+

+import org.apache.poi.hssf.usermodel.HSSFConditionalFormatting;

+import org.apache.poi.hssf.usermodel.HSSFConditionalFormattingRule;

 import org.apache.poi.ss.ITestDataProvider;

+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;

+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;

 import org.apache.poi.ss.util.CellRangeAddress;

 

 /**

- * @author Dmitriy Kumshayev

- * @author Yegor Kozlov

+ * Base tests for Conditional Formatting, for both HSSF and XSSF

  */

 public abstract class BaseTestConditionalFormatting extends TestCase {

     private final ITestDataProvider _testDataProvider;

@@ -33,6 +37,8 @@
     public BaseTestConditionalFormatting(ITestDataProvider testDataProvider){

         _testDataProvider = testDataProvider;

     }

+    

+    protected abstract void assertColour(String hexExpected, Color actual);

 

     public void testBasic() {

         Workbook wb = _testDataProvider.createWorkbook();

@@ -101,7 +107,8 @@
         SheetConditionalFormatting sheetCF = sh.getSheetConditionalFormatting();

 

         ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("SUM(A1:A5)>10");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_FORMULA, rule1.getConditionType());

+        assertEquals(ConditionType.FORMULA.id, rule1.getConditionType());

+        assertEquals(ConditionType.FORMULA, rule1.getConditionTypeType());

         assertEquals("SUM(A1:A5)>10", rule1.getFormula1());

         int formatIndex1 = sheetCF.addConditionalFormatting(

                 new CellRangeAddress[]{

@@ -136,56 +143,65 @@
 

         ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.EQUAL, "SUM(A1:A5)+10");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule1.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule1.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule1.getConditionTypeType());

         assertEquals("SUM(A1:A5)+10", rule1.getFormula1());

         assertEquals(ComparisonOperator.EQUAL, rule1.getComparisonOperation());

 

         ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.NOT_EQUAL, "15");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule2.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule2.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule2.getConditionTypeType());

         assertEquals("15", rule2.getFormula1());

         assertEquals(ComparisonOperator.NOT_EQUAL, rule2.getComparisonOperation());

 

         ConditionalFormattingRule rule3 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.NOT_EQUAL, "15");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule3.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule3.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule3.getConditionTypeType());

         assertEquals("15", rule3.getFormula1());

         assertEquals(ComparisonOperator.NOT_EQUAL, rule3.getComparisonOperation());

 

         ConditionalFormattingRule rule4 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.GT, "0");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule4.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule4.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule4.getConditionTypeType());

         assertEquals("0", rule4.getFormula1());

         assertEquals(ComparisonOperator.GT, rule4.getComparisonOperation());

 

         ConditionalFormattingRule rule5 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.LT, "0");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule5.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule5.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule5.getConditionTypeType());

         assertEquals("0", rule5.getFormula1());

         assertEquals(ComparisonOperator.LT, rule5.getComparisonOperation());

 

         ConditionalFormattingRule rule6 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.GE, "0");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule6.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule6.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule6.getConditionTypeType());

         assertEquals("0", rule6.getFormula1());

         assertEquals(ComparisonOperator.GE, rule6.getComparisonOperation());

 

         ConditionalFormattingRule rule7 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.LE, "0");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule7.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule7.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule7.getConditionTypeType());

         assertEquals("0", rule7.getFormula1());

         assertEquals(ComparisonOperator.LE, rule7.getComparisonOperation());

 

         ConditionalFormattingRule rule8 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.BETWEEN, "0", "5");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule8.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule8.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule8.getConditionTypeType());

         assertEquals("0", rule8.getFormula1());

         assertEquals("5", rule8.getFormula2());

         assertEquals(ComparisonOperator.BETWEEN, rule8.getComparisonOperation());

 

         ConditionalFormattingRule rule9 = sheetCF.createConditionalFormattingRule(

                 ComparisonOperator.NOT_BETWEEN, "0", "5");

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule9.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS.id, rule9.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule9.getConditionTypeType());

         assertEquals("0", rule9.getFormula1());

         assertEquals("5", rule9.getFormula2());

         assertEquals(ComparisonOperator.NOT_BETWEEN, rule9.getComparisonOperation());

@@ -455,7 +471,7 @@
 

         // CF1 has two rules: values less than -3 are bold-italic red, values greater than 3 are green

         ConditionalFormattingRule rule1 = cf1.getRule(0);

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule1.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule1.getConditionTypeType());

         assertEquals(ComparisonOperator.GT, rule1.getComparisonOperation());

         assertEquals("3", rule1.getFormula1());

         assertNull(rule1.getFormula2());

@@ -469,7 +485,7 @@
         assertFalse(fmt1.isItalic());

 

         ConditionalFormattingRule rule2 = cf1.getRule(1);

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule2.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule2.getConditionTypeType());

         assertEquals(ComparisonOperator.LT, rule2.getComparisonOperation());

         assertEquals("-3", rule2.getFormula1());

         assertNull(rule2.getFormula2());

@@ -489,7 +505,7 @@
         assertEquals("B9", regions2[0].formatAsString());

 

         ConditionalFormattingRule rule3 = cf2.getRule(0);

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_FORMULA, rule3.getConditionType());

+        assertEquals(ConditionType.FORMULA, rule3.getConditionTypeType());

         assertEquals(ComparisonOperator.NO_COMPARISON, rule3.getComparisonOperation());

         assertEquals("$A$8>5", rule3.getFormula1());

         assertNull(rule3.getFormula2());

@@ -513,18 +529,210 @@
         assertEquals(2, cf3.getNumberOfRules());

 

         ConditionalFormattingRule rule4 = cf3.getRule(0);

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule4.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule4.getConditionTypeType());

         assertEquals(ComparisonOperator.LE, rule4.getComparisonOperation());

         assertEquals("\"AAA\"", rule4.getFormula1());

         assertNull(rule4.getFormula2());

 

         ConditionalFormattingRule rule5 = cf3.getRule(1);

-        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule5.getConditionType());

+        assertEquals(ConditionType.CELL_VALUE_IS, rule5.getConditionTypeType());

         assertEquals(ComparisonOperator.BETWEEN, rule5.getComparisonOperation());

         assertEquals("\"A\"", rule5.getFormula1());

         assertEquals("\"AAA\"", rule5.getFormula2());

     }

 

+    public void testReadOffice2007(String filename) {

+        Workbook wb = _testDataProvider.openSampleWorkbook(filename);

+        Sheet s = wb.getSheet("CF");

+        ConditionalFormatting cf = null;

+        ConditionalFormattingRule cr = null;

+        IconMultiStateFormatting icon = null;

+        ConditionalFormattingThreshold th = null;

+        

+        // Sanity check data

+        assertEquals("Values", s.getRow(0).getCell(0).toString());

+        assertEquals("10.0", s.getRow(2).getCell(0).toString());

+

+        // Check we found all the conditional formattings rules we should have

+        SheetConditionalFormatting sheetCF = s.getSheetConditionalFormatting();

+        int numCF = 3;

+        int numCF12 = 15;

+        int numCFEX = 0; // TODO This should be 1, but we don't support CFEX formattings yet

+        assertEquals(numCF+numCF12+numCFEX, sheetCF.getNumConditionalFormattings());

+        

+        int fCF = 0, fCF12 = 0, fCFEX = 0;

+        for (int i=0; i<sheetCF.getNumConditionalFormattings(); i++) {

+            cf = sheetCF.getConditionalFormattingAt(i);

+            if (cf instanceof HSSFConditionalFormatting) {

+                String str = cf.toString();

+                if (str.contains("[CF]")) fCF++;

+                if (str.contains("[CF12]")) fCF12++;

+                if (str.contains("[CFEX]")) fCFEX++;

+            } else {

+                ConditionType type = cf.getRule(cf.getNumberOfRules()-1).getConditionTypeType();

+                if (type == ConditionType.CELL_VALUE_IS ||

+                    type == ConditionType.FORMULA) {

+                    fCF++;

+                } else {

+                    // TODO Properly detect Ext ones from the xml

+                    fCF12++;

+                }

+            }

+        }

+        assertEquals(numCF, fCF);

+        assertEquals(numCF12, fCF12);

+        assertEquals(numCFEX, fCFEX);

+        

+        

+        // Check the rules / values in detail

+        

+        

+        // Highlight Positive values - Column C

+        cf = sheetCF.getConditionalFormattingAt(0);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("C2:C17", cf.getFormattingRanges()[0].formatAsString());

+        

+        assertEquals(1, cf.getNumberOfRules());

+        cr = cf.getRule(0);

+        assertEquals(ConditionType.CELL_VALUE_IS, cr.getConditionTypeType());

+        assertEquals(ComparisonOperator.GT, cr.getComparisonOperation());

+        assertEquals("0", cr.getFormula1());

+        assertEquals(null, cr.getFormula2());

+        // When it matches:

+        //   Sets the font colour to dark green

+        //   Sets the background colour to lighter green

+        // TODO Should the colours be slightly different between formats? Would CFEX support help for HSSF?

+        if (cr instanceof HSSFConditionalFormattingRule) {

+            assertColour("0:8080:0", cr.getFontFormatting().getFontColor());

+            assertColour("CCCC:FFFF:CCCC", cr.getPatternFormatting().getFillBackgroundColorColor());

+        } else {

+            assertColour("006100", cr.getFontFormatting().getFontColor());

+            assertColour("C6EFCE", cr.getPatternFormatting().getFillBackgroundColorColor());

+        }

+        

+        

+        // Highlight 10-30 - Column D

+        cf = sheetCF.getConditionalFormattingAt(1);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("D2:D17", cf.getFormattingRanges()[0].formatAsString());

+        

+        assertEquals(1, cf.getNumberOfRules());

+        cr = cf.getRule(0);

+        assertEquals(ConditionType.CELL_VALUE_IS, cr.getConditionTypeType());

+        assertEquals(ComparisonOperator.BETWEEN, cr.getComparisonOperation());

+        assertEquals("10", cr.getFormula1());

+        assertEquals("30", cr.getFormula2());

+        // When it matches:

+        //   Sets the font colour to dark red

+        //   Sets the background colour to lighter red

+        // TODO Should the colours be slightly different between formats? Would CFEX support help for HSSF?

+        if (cr instanceof HSSFConditionalFormattingRule) {

+            assertColour("8080:0:8080", cr.getFontFormatting().getFontColor());

+            assertColour("FFFF:9999:CCCC", cr.getPatternFormatting().getFillBackgroundColorColor());

+        } else {

+            assertColour("9C0006", cr.getFontFormatting().getFontColor());

+            assertColour("FFC7CE", cr.getPatternFormatting().getFillBackgroundColorColor());

+        }

+

+        

+        // Data Bars - Column E

+        cf = sheetCF.getConditionalFormattingAt(2);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("E2:E17", cf.getFormattingRanges()[0].formatAsString());

+        

+        assertEquals(1, cf.getNumberOfRules());

+        cr = cf.getRule(0);

+        assertEquals(ConditionType.DATA_BAR, cr.getConditionTypeType());

+        // TODO Support Data Bars, then check the rest of this rule

+        

+        

+        // Colours R->G - Column F

+        cf = sheetCF.getConditionalFormattingAt(3);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("F2:F17", cf.getFormattingRanges()[0].formatAsString());

+        

+        assertEquals(1, cf.getNumberOfRules());

+        cr = cf.getRule(0);

+        assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());

+        // TODO Support Color Scales, then check the rest of this rule

+

+        

+        // Colours BWR - Column G

+        cf = sheetCF.getConditionalFormattingAt(4);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("G2:G17", cf.getFormattingRanges()[0].formatAsString());

+        

+        assertEquals(1, cf.getNumberOfRules());

+        cr = cf.getRule(0);

+        assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());

+        // TODO Support Color Scales, then check the rest of this rule

+

+        

+        // Icons : Default - Column H, percentage thresholds

+        cf = sheetCF.getConditionalFormattingAt(5);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("H2:H17", cf.getFormattingRanges()[0].formatAsString());

+        assertIconSetPercentages(cf, IconSet.GYR_3_TRAFFIC_LIGHTS, 0d, 33d, 67d);

+        

+        

+        // Icons : 3 signs - Column I

+        cf = sheetCF.getConditionalFormattingAt(6);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("I2:I17", cf.getFormattingRanges()[0].formatAsString());

+        assertIconSetPercentages(cf, IconSet.GYR_3_SHAPES, 0d, 33d, 67d);

+        

+        

+        // Icons : 3 traffic lights 2 - Column J

+        cf = sheetCF.getConditionalFormattingAt(7);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("J2:J17", cf.getFormattingRanges()[0].formatAsString());

+        assertIconSetPercentages(cf, IconSet.GYR_3_TRAFFIC_LIGHTS_BOX, 0d, 33d, 67d);

+        

+        

+        // Icons : 4 traffic lights - Column K

+        cf = sheetCF.getConditionalFormattingAt(8);

+        assertEquals(1, cf.getFormattingRanges().length);

+        assertEquals("K2:K17", cf.getFormattingRanges()[0].formatAsString());

+        assertIconSetPercentages(cf, IconSet.GYRB_4_TRAFFIC_LIGHTS, 0d, 25d, 50d, 75d);

+

+        

+        // Icons : 3 symbols - Column L

+        // Icons : 3 flags - Column M

+        // Icons : 3 symbols 2 - Column N

+        // Icons : 3 arrows - Column O     

+        // Icons : 5 arrows grey - Column P    

+        // Icons : 3 stars (ext) - Column Q

+        // Icons : 4 ratings - Column R

+        // Icons : 5 ratings - Column S

+        // Custom Icon+Format - Column T

+        // Mixed icons - Column U

+

+    }

+    private void assertIconSetPercentages(ConditionalFormatting cf, IconSet iconset, Double...vals) {

+        assertEquals(1, cf.getNumberOfRules());

+        ConditionalFormattingRule cr = cf.getRule(0);

+        

+        assertEquals(ConditionType.ICON_SET, cr.getConditionTypeType());

+        assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());

+        assertEquals(null, cr.getFormula1());

+        assertEquals(null, cr.getFormula2());

+        

+        IconMultiStateFormatting icon = cr.getMultiStateFormatting();

+        assertNotNull(icon);

+        assertEquals(iconset, icon.getIconSet());

+        assertEquals(false, icon.isIconOnly());

+        assertEquals(false, icon.isReversed());

+        

+        assertNotNull(icon.getThresholds());

+        assertEquals(vals.length, icon.getThresholds().length);

+        for (int i=0; i<vals.length; i++) {

+            Double v = vals[i];

+            ConditionalFormattingThreshold th = icon.getThresholds()[i];

+            assertEquals(RangeType.PERCENT, th.getRangeType());

+            assertEquals(v, th.getValue());

+            assertEquals(null, th.getFormula());

+        }

+    }

 

     public void testCreateFontFormatting() {

         Workbook workbook = _testDataProvider.createWorkbook();

@@ -699,6 +907,57 @@
         assertEquals(BorderFormatting.BORDER_HAIR, r1fp.getBorderRight());

     }

     

+    // TODO Fix this test to work for HSSF

+    public void DISABLEDtestCreateIconFormatting() {

+        Workbook workbook = _testDataProvider.createWorkbook();

+        Sheet sheet = workbook.createSheet();

+

+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();

+        ConditionalFormattingRule rule1 = 

+                sheetCF.createConditionalFormattingRule(IconSet.GYRB_4_TRAFFIC_LIGHTS);

+        IconMultiStateFormatting iconFmt = rule1.getMultiStateFormatting();

+        

+        assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet());

+        assertEquals(4, iconFmt.getThresholds().length);

+        assertEquals(false, iconFmt.isIconOnly());

+        assertEquals(false, iconFmt.isReversed());

+        

+        iconFmt.setIconOnly(true);

+        iconFmt.getThresholds()[0].setRangeType(RangeType.MIN);

+        iconFmt.getThresholds()[1].setRangeType(RangeType.NUMBER);

+        iconFmt.getThresholds()[1].setValue(10d);

+        iconFmt.getThresholds()[2].setRangeType(RangeType.PERCENT);

+        iconFmt.getThresholds()[2].setValue(75d);

+        iconFmt.getThresholds()[3].setRangeType(RangeType.MAX);

+        

+        CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") };

+        sheetCF.addConditionalFormatting(regions, rule1);

+        

+        // Save, re-load and re-check

+        workbook = _testDataProvider.writeOutAndReadBack(workbook);

+        sheetCF = sheet.getSheetConditionalFormatting();

+        assertEquals(1, sheetCF.getNumConditionalFormattings());

+        

+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);

+        assertEquals(1, cf.getNumberOfRules());

+        rule1 = cf.getRule(0);

+        iconFmt = rule1.getMultiStateFormatting();

+        

+        assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet());

+        assertEquals(4, iconFmt.getThresholds().length);

+        assertEquals(true, iconFmt.isIconOnly());

+        assertEquals(false, iconFmt.isReversed());

+

+        assertEquals(RangeType.MIN,    iconFmt.getThresholds()[0].getRangeType());

+        assertEquals(RangeType.NUMBER, iconFmt.getThresholds()[1].getRangeType());

+        assertEquals(RangeType.PERCENT,iconFmt.getThresholds()[2].getRangeType());

+        assertEquals(RangeType.MAX,    iconFmt.getThresholds()[3].getRangeType());

+        assertEquals(null, iconFmt.getThresholds()[0].getValue());

+        assertEquals(10d,  iconFmt.getThresholds()[1].getValue());

+        assertEquals(75d,  iconFmt.getThresholds()[2].getValue());

+        assertEquals(null, iconFmt.getThresholds()[3].getValue());

+    }

+    

     public void testBug55380() {

         Workbook wb = _testDataProvider.createWorkbook();

         Sheet sheet = wb.createSheet();

diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java
index d013bea..2ae096a 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.usermodel;
 
+import java.io.IOException;
 import java.util.Iterator;
 
 import junit.framework.TestCase;
@@ -137,7 +138,8 @@
             fail("expected exception");
         } catch (IllegalArgumentException e) {
             // expected during successful test
-            assertTrue(e.getMessage().startsWith("Invalid row number (-1)"));
+            assertTrue("Did not find expected error message, had: " + e, 
+                    e.getMessage().startsWith("Invalid row number (-1)"));
         }
 
         //Test high row bound
@@ -284,7 +286,7 @@
         assertEquals(Cell.CELL_TYPE_NUMERIC, row.getCell(5).getCellType());
     }
 
-    public void testRowHeight() {
+    public void testRowHeight() throws IOException {
         Workbook workbook = _testDataProvider.createWorkbook();
         Sheet sheet = workbook.createSheet();
         Row row1 = sheet.createRow(0);
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java
index 480235f..55f9795 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java
@@ -17,17 +17,13 @@
 
 package org.apache.poi.ss.usermodel;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.*;
 
+import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
@@ -41,13 +37,15 @@
  * {@link org.apache.poi.hssf.usermodel.HSSFCell}
  */
 public abstract class BaseTestSheet {
+    private static final int ROW_COUNT = 40000;
+
     @Rule
     public ExpectedException thrown = ExpectedException.none();
     
     private final ITestDataProvider _testDataProvider;
 
     protected BaseTestSheet(ITestDataProvider testDataProvider) {
-    _testDataProvider = testDataProvider;
+    	_testDataProvider = testDataProvider;
     }
 
     @Test
@@ -851,22 +849,126 @@
     }
 
     @Test
-    public void bug55723_Rows() {
-        HSSFWorkbook wb = new HSSFWorkbook();
+    public void bug55723_Rows() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
         Sheet sheet = wb.createSheet();
 
         CellRangeAddress range = CellRangeAddress.valueOf("A4:B55000");
         AutoFilter filter = sheet.setAutoFilter(range);
         assertNotNull(filter);
+        
+        wb.close();
     }
 
     @Test
-    public void bug55723d_RowsOver65k() {
-        HSSFWorkbook wb = new HSSFWorkbook();
+    public void bug55723d_RowsOver65k() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
         Sheet sheet = wb.createSheet();
 
         CellRangeAddress range = CellRangeAddress.valueOf("A4:B75000");
         AutoFilter filter = sheet.setAutoFilter(range);
         assertNotNull(filter);
+        
+        wb.close();
+    }
+
+    /**
+     * XSSFSheet autoSizeColumn() on empty RichTextString fails
+     * @throws IOException 
+     */
+    @Test
+    public void bug48325() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Test");
+        CreationHelper factory = wb.getCreationHelper();
+
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+
+        Font font = wb.createFont();
+        RichTextString rts = factory.createRichTextString("");
+        rts.applyFont(font);
+        cell.setCellValue(rts);
+
+        sheet.autoSizeColumn(0);
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(wb));
+        
+        wb.close();
+    }
+
+    @Test
+    public void getCellComment() throws IOException {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet();
+        Drawing dg = sheet.createDrawingPatriarch();
+        Comment comment = dg.createCellComment(workbook.getCreationHelper().createClientAnchor());
+        Cell cell = sheet.createRow(9).createCell(2);
+        comment.setAuthor("test C10 author");
+        cell.setCellComment(comment);
+
+        assertNotNull(sheet.getCellComment(9, 2));
+        assertEquals("test C10 author", sheet.getCellComment(9, 2).getAuthor());
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(workbook));
+        
+        workbook.close();
+    }
+
+
+    @Test
+    public void newMergedRegionAt() throws IOException {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet();
+        CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
+        sheet.addMergedRegion(region);
+        assertEquals("B2:D4", sheet.getMergedRegion(0).formatAsString());
+        assertEquals(1, sheet.getNumMergedRegions());
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(workbook));
+        
+        workbook.close();
+    }
+
+    @Test
+    public void showInPaneManyRowsBug55248() {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet("Sheet 1");
+
+        sheet.showInPane(0, 0);
+
+        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
+            sheet.createRow(i);
+            sheet.showInPane(i, 0);
+            // this one fails: sheet.showInPane((short)i, 0);
+        }
+
+        int i = 0;
+        sheet.showInPane(i, i);
+
+        Workbook wb = _testDataProvider.writeOutAndReadBack(workbook);
+        checkRowCount(wb);
+    }
+
+    private void checkRowCount(Workbook wb) {
+        assertNotNull(wb);
+        final Sheet sh = wb.getSheet("Sheet 1");
+        assertNotNull(sh);
+        assertEquals(ROW_COUNT-1, sh.getLastRowNum());
+    }
+    
+    
+    @Test
+    public void testRightToLeft() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet();
+
+        assertFalse(sheet.isRightToLeft());
+        sheet.setRightToLeft(true);
+        assertTrue(sheet.isRightToLeft());
+        sheet.setRightToLeft(false);
+        assertFalse(sheet.isRightToLeft());
+        
+        wb.close();
     }
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
index 9146db7..512b4a7 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
@@ -17,8 +17,11 @@
 
 package org.apache.poi.ss.usermodel;
 
+import java.io.IOException;
+
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
@@ -134,8 +137,7 @@
         assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6));
     }
 
-    public void testShiftWithComments() { // TODO - enable XSSF test
-
+    public void testShiftWithComments() {
         Workbook wb = _testDataProvider.openSampleWorkbook("comments." + _testDataProvider.getStandardFileNameExtension());
 
         Sheet sheet = wb.getSheet("Sheet1");
@@ -154,6 +156,8 @@
         String comment4 = sheet.getCellComment(3,0).getString().getString();
         assertEquals(comment4,"comment top row4 (index3)\n");
 
+        //Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb);
+
         // Shifting all but first line down to test comments shifting
         sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true);
 
@@ -191,6 +195,26 @@
         assertEquals(comment3,comment3_shifted);
         comment4_shifted = sheet.getCellComment(4,0).getString().getString();
         assertEquals(comment4,comment4_shifted);
+
+        // Shifting back up again, now two rows
+        sheet.shiftRows(2, sheet.getLastRowNum(), -2, true, true);
+
+        // TODO: it seems HSSFSheet does not correctly remove comments from rows that are overwritten
+        // by shifting rows...
+        if(!(wb instanceof HSSFWorkbook)) {
+        	assertEquals(2, sheet.getLastRowNum());
+        	
+        	// Verify comments are in the position expected
+        	assertNull("Had: " + (sheet.getCellComment(0,0) == null ? "null" : sheet.getCellComment(0,0).getString()),
+        			sheet.getCellComment(0,0));
+        	assertNotNull(sheet.getCellComment(1,0));
+        	assertNotNull(sheet.getCellComment(2,0));
+        }
+
+        comment1 = sheet.getCellComment(1,0).getString().getString();
+        assertEquals(comment1,"comment top row3 (index2)\n");
+        String comment2 = sheet.getCellComment(2,0).getString().getString();
+        assertEquals(comment2,"comment top row4 (index3)\n");
     }
 
     public final void testShiftWithNames() {
@@ -378,6 +402,28 @@
 
         assertEquals("SUM(G29:I29)", sheet.getRow(28).getCell(9).getCellFormula());
         assertEquals("SUM(G30:I30)", sheet.getRow(29).getCell(9).getCellFormula());
-
     }
-}
\ No newline at end of file
+
+	public void testBug55280() throws IOException {
+        Workbook w = _testDataProvider.createWorkbook();
+        try {
+            Sheet s = w.createSheet();
+            for (int row = 0; row < 5000; ++row)
+                s.addMergedRegion(new CellRangeAddress(row, row, 0, 3));
+
+            s.shiftRows(0, 4999, 1);        // takes a long time...
+        } finally {
+            w.close();
+        }
+	}
+
+    public void test47169() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet();
+        sheet.createRow(30);
+        sheet.shiftRows(29, 29, 1, true, true);
+        sheet.createRow(30);
+
+        wb.close();
+    }
+}
diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java b/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java
new file mode 100644
index 0000000..870cd9c
--- /dev/null
+++ b/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java
@@ -0,0 +1,92 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.usermodel;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.junit.Test;
+
+public class TestDateUtil {
+
+    @Test
+    public void getJavaDate_InvalidValue() {
+        double dateValue = -1;
+        TimeZone tz = TimeZone.getDefault();
+        boolean use1904windowing = false;
+        boolean roundSeconds = false;
+
+        assertEquals(null, DateUtil.getJavaDate(dateValue));
+        assertEquals(null, DateUtil.getJavaDate(dateValue, tz));
+        assertEquals(null, DateUtil.getJavaDate(dateValue, use1904windowing));
+        assertEquals(null, DateUtil.getJavaDate(dateValue, use1904windowing, tz));
+        assertEquals(null, DateUtil.getJavaDate(dateValue, use1904windowing, tz, roundSeconds));
+    }
+
+    @Test
+    public void getJavaDate_ValidValue() {
+        double dateValue = 0;
+        TimeZone tz = TimeZone.getDefault();
+        boolean use1904windowing = false;
+        boolean roundSeconds = false;
+
+        Calendar calendar = Calendar.getInstance(tz);
+        calendar.set(1900, 0, 0, 0, 0, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        Date date = calendar.getTime();
+
+        assertEquals(date, DateUtil.getJavaDate(dateValue));
+        assertEquals(date, DateUtil.getJavaDate(dateValue, tz));
+        assertEquals(date, DateUtil.getJavaDate(dateValue, use1904windowing));
+        assertEquals(date, DateUtil.getJavaDate(dateValue, use1904windowing, tz));
+        assertEquals(date, DateUtil.getJavaDate(dateValue, use1904windowing, tz, roundSeconds));
+    }
+
+    @Test
+    public void getJavaCalendar_InvalidValue() {
+        double dateValue = -1;
+        TimeZone tz = TimeZone.getDefault();
+        boolean use1904windowing = false;
+        boolean roundSeconds = false;
+
+        assertEquals(null, DateUtil.getJavaCalendar(dateValue));
+        assertEquals(null, DateUtil.getJavaCalendar(dateValue, use1904windowing));
+        assertEquals(null, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz));
+        assertEquals(null, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz, roundSeconds));
+    }
+
+    @Test
+    public void getJavaCalendar_ValidValue() {
+        double dateValue = 0;
+        TimeZone tz = TimeZone.getDefault();
+        boolean use1904windowing = false;
+        boolean roundSeconds = false;
+
+        Calendar calendar = Calendar.getInstance(tz);
+        calendar.set(1900, 0, 0, 0, 0, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+
+        assertEquals(calendar, DateUtil.getJavaCalendar(dateValue));
+        assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing));
+        assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz));
+        assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz, roundSeconds));
+    }
+}
diff --git a/src/testcases/org/apache/poi/ss/util/TestAreaReference.java b/src/testcases/org/apache/poi/ss/util/TestAreaReference.java
new file mode 100644
index 0000000..de2226d
--- /dev/null
+++ b/src/testcases/org/apache/poi/ss/util/TestAreaReference.java
@@ -0,0 +1,71 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.ss.util;
+
+import org.apache.poi.ss.SpreadsheetVersion;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for {@link AreaReference} handling of max rows.
+ * 
+ * @author David North
+ */
+public class TestAreaReference extends TestCase {
+    
+    public void testWholeColumn() {
+        AreaReference oldStyle = AreaReference.getWholeColumn(SpreadsheetVersion.EXCEL97, "A", "B");
+        assertEquals(0, oldStyle.getFirstCell().getCol());
+        assertEquals(0, oldStyle.getFirstCell().getRow());
+        assertEquals(1, oldStyle.getLastCell().getCol());
+        assertEquals(SpreadsheetVersion.EXCEL97.getLastRowIndex(), oldStyle.getLastCell().getRow());
+        assertTrue(oldStyle.isWholeColumnReference());
+
+        AreaReference oldStyleNonWholeColumn = new AreaReference("A1:B23", SpreadsheetVersion.EXCEL97);
+        assertFalse(oldStyleNonWholeColumn.isWholeColumnReference());
+
+        AreaReference newStyle = AreaReference.getWholeColumn(SpreadsheetVersion.EXCEL2007, "A", "B");
+        assertEquals(0, newStyle.getFirstCell().getCol());
+        assertEquals(0, newStyle.getFirstCell().getRow());
+        assertEquals(1, newStyle.getLastCell().getCol());
+        assertEquals(SpreadsheetVersion.EXCEL2007.getLastRowIndex(), newStyle.getLastCell().getRow());
+        assertTrue(newStyle.isWholeColumnReference());
+
+        AreaReference newStyleNonWholeColumn = new AreaReference("A1:B23", SpreadsheetVersion.EXCEL2007);
+        assertFalse(newStyleNonWholeColumn.isWholeColumnReference());
+    }
+    
+    public void testWholeRow() {
+        AreaReference oldStyle = AreaReference.getWholeRow(SpreadsheetVersion.EXCEL97, "1", "2");
+        assertEquals(0, oldStyle.getFirstCell().getCol());
+        assertEquals(0, oldStyle.getFirstCell().getRow());
+        assertEquals(SpreadsheetVersion.EXCEL97.getLastColumnIndex(), oldStyle.getLastCell().getCol());
+        assertEquals(1, oldStyle.getLastCell().getRow());
+        
+        AreaReference newStyle = AreaReference.getWholeRow(SpreadsheetVersion.EXCEL2007, "1", "2");
+        assertEquals(0, newStyle.getFirstCell().getCol());
+        assertEquals(0, newStyle.getFirstCell().getRow());
+        assertEquals(SpreadsheetVersion.EXCEL2007.getLastColumnIndex(), newStyle.getLastCell().getCol());
+        assertEquals(1, newStyle.getLastCell().getRow());
+    }
+
+    @SuppressWarnings("deprecation") // deliberate test for behaviour if deprecated constructor used.
+    public void testFallbackToExcel97IfVersionNotSupplied() {
+        assertTrue(new AreaReference("A:B").isWholeColumnReference());
+        assertTrue(AreaReference.isWholeColumnReference(null, new CellReference("A$1"), new CellReference("A$" + SpreadsheetVersion.EXCEL97.getMaxRows())));
+    }
+}
diff --git a/src/testcases/org/apache/poi/ss/util/TestSheetUtil.java b/src/testcases/org/apache/poi/ss/util/TestSheetUtil.java
index c8f5d91..5d94d3e 100644
--- a/src/testcases/org/apache/poi/ss/util/TestSheetUtil.java
+++ b/src/testcases/org/apache/poi/ss/util/TestSheetUtil.java
@@ -17,13 +17,16 @@
 
 package org.apache.poi.ss.util;
 
-import junit.framework.TestCase;
+import java.io.IOException;
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 
+import junit.framework.TestCase;
+
 /**
  * Tests SheetUtil.
  *
@@ -61,5 +64,86 @@
         assertEquals(21.0, SheetUtil.getCellWithMerges(s, 2, 2).getNumericCellValue());
         assertEquals(21.0, SheetUtil.getCellWithMerges(s, 2, 3).getNumericCellValue());
         assertEquals(21.0, SheetUtil.getCellWithMerges(s, 2, 4).getNumericCellValue());
+        
+        wb.close();
     }
-}
\ No newline at end of file
+    
+    public void testCanComputeWidthHSSF() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        
+        // cannot check on result because on some machines we get back false here!
+        SheetUtil.canComputeColumnWidht(wb.getFontAt((short)0));
+
+        wb.close();        
+    }
+
+    public void testGetCellWidthEmpty() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = wb.createSheet("sheet");
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+        
+        // no contents: cell.setCellValue("sometext");
+        
+        assertEquals(-1.0, SheetUtil.getCellWidth(cell, 1, null, true));
+        
+        wb.close();
+    }
+
+    public void testGetCellWidthString() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = wb.createSheet("sheet");
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+        
+        cell.setCellValue("sometext");
+        
+        assertTrue(SheetUtil.getCellWidth(cell, 1, null, true) > 0);
+        
+        wb.close();
+    }
+
+    public void testGetCellWidthNumber() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = wb.createSheet("sheet");
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+        
+        cell.setCellValue(88.234);
+        
+        assertTrue(SheetUtil.getCellWidth(cell, 1, null, true) > 0);
+        
+        wb.close();
+    }
+
+    public void testGetCellWidthBoolean() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = wb.createSheet("sheet");
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+        
+        cell.setCellValue(false);
+        
+        assertTrue(SheetUtil.getCellWidth(cell, 1, null, false) > 0);
+        
+        wb.close();
+    }
+
+    public void testGetColumnWidthString() throws IOException {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = wb.createSheet("sheet");
+        Row row = sheet.createRow(0);
+        sheet.createRow(1);
+        sheet.createRow(2);
+        Cell cell = row.createCell(0);
+        
+        cell.setCellValue("sometext");
+        
+        assertTrue("Having some width for rows with actual cells", 
+                SheetUtil.getColumnWidth(sheet, 0, true) > 0);
+        assertEquals("Not having any widht for rows with all empty cells", 
+                -1.0, SheetUtil.getColumnWidth(sheet, 0, true, 1, 2));
+        
+        wb.close();
+    }
+}
diff --git a/src/testcases/org/apache/poi/util/AllPOIUtilTests.java b/src/testcases/org/apache/poi/util/AllPOIUtilTests.java
index de6739b..34ad0f4 100644
--- a/src/testcases/org/apache/poi/util/AllPOIUtilTests.java
+++ b/src/testcases/org/apache/poi/util/AllPOIUtilTests.java
@@ -17,30 +17,29 @@
 
 package org.apache.poi.util;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
 
 /**
  * Test suite for all sub-packages of org.apache.poi.util<br/>
  */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+      TestArrayUtil.class
+    , TestBinaryTree.class
+    , TestBitField.class
+    , TestByteField.class
+    , TestHexDump.class
+    , TestIntegerField.class
+    , TestIntList.class
+    , TestLittleEndian.class
+    , TestLongField.class
+    , TestPOILogFactory.class
+    , TestPOILogger.class
+    , TestShortField.class
+    , TestShortList.class
+    , TestStringUtil.class
+    , TestTempFile.class
+})
 public final class AllPOIUtilTests {
-    public static Test suite() {
-        TestSuite result = new TestSuite(AllPOIUtilTests.class.getName());
-        result.addTestSuite(TestArrayUtil.class);
-        result.addTestSuite(TestBinaryTree.class);
-        result.addTestSuite(TestBitField.class);
-        result.addTestSuite(TestByteField.class);
-        result.addTestSuite(TestHexDump.class);
-        result.addTestSuite(TestIntegerField.class);
-        result.addTestSuite(TestIntList.class);
-        result.addTestSuite(TestLittleEndian.class);
-        result.addTestSuite(TestLongField.class);
-        result.addTestSuite(TestPOILogFactory.class);
-        result.addTestSuite(TestPOILogger.class);
-        result.addTestSuite(TestShortField.class);
-        result.addTestSuite(TestShortList.class);
-        result.addTestSuite(TestStringUtil.class);
-        result.addTestSuite(TestTempFile.class);
-        return result;
-    }
 }
diff --git a/src/testcases/org/apache/poi/util/TestPOILogger.java b/src/testcases/org/apache/poi/util/TestPOILogger.java
index a3d34fa..7fc5824 100644
--- a/src/testcases/org/apache/poi/util/TestPOILogger.java
+++ b/src/testcases/org/apache/poi/util/TestPOILogger.java
@@ -18,7 +18,13 @@
 
 package org.apache.poi.util;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+
+import org.junit.Test;
 
 /**
  * Tests the log class.
@@ -27,23 +33,62 @@
  * @author Marc Johnson (mjohnson at apache dot org)
  * @author Nicola Ken Barozzi (nicolaken at apache.org)
  */
-public final class TestPOILogger extends TestCase {
-
+public final class TestPOILogger extends POILogger {
+    private String lastLog = "";
+    private Throwable lastEx = null;
+    
     /**
      * Test different types of log output.
      */
-    public void testVariousLogTypes() {
-        //NKB Testing only that logging classes use gives no exception
-        //    Since logging can be disabled, no checking of logging
-        //    output is done.
+    @Test
+    public void testVariousLogTypes() throws Exception {
+        Field f = POILogFactory.class.getDeclaredField("_loggerClassName");
+        f.setAccessible(true);
+        String oldLCN = (String)f.get(null);
+        try {
+            f.set(null, TestPOILogger.class.getName());
+            POILogger log = POILogFactory.getLogger( "foo" );
+            assertTrue(log instanceof TestPOILogger);
+            
+            TestPOILogger tlog = (TestPOILogger)log;
+    
+            log.log(POILogger.WARN, "Test = ", 1);
+            assertEquals("Test = 1", tlog.lastLog);
+            
+            log.logFormatted(POILogger.ERROR, "Test param 1 = %, param 2 = %d", "2", 3 );
+            assertEquals("Test param 1 = 2, param 2 = 3", tlog.lastLog);
+            
+            log.logFormatted(POILogger.ERROR, "Test param 1 = %d, param 2 = %", new int[]{4, 5} );
+            assertEquals("Test param 1 = 4, param 2 = 5", tlog.lastLog);
+            
+            log.logFormatted(POILogger.ERROR, "Test param 1 = %1.1, param 2 = %0.1", new double[]{4, 5.23} );
+            assertEquals("Test param 1 = 4, param 2 = 5.2", tlog.lastLog);
 
-        POILogger log = POILogFactory.getLogger( "foo" );
+            log.log(POILogger.ERROR, "Test ", 1,2,new Exception("bla"));
+            assertEquals("Test 12", tlog.lastLog);
+            assertNotNull(tlog.lastEx);
+            
+            log.log(POILogger.ERROR, "log\nforging", "\nevil","\nlog");
+            assertEquals("log forging evil log", tlog.lastLog);
+        } finally {
+            f.set(null, oldLCN);
+        }
+    }
 
-        log.log( POILogger.WARN, "Test = ", Integer.valueOf( 1 ) );
-        log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", "2", Integer.valueOf( 3 ) );
-        log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", new int[]{4, 5} );
-        log.logFormatted( POILogger.ERROR,
-                "Test param 1 = %1.1, param 2 = %0.1", new double[]{4, 5.23} );
+    public void initialize(String cat) {
+    }
 
+    public void log(int level, Object obj1) {
+        lastLog = (obj1 == null) ? "" : obj1.toString();
+        lastEx = null;
+    }
+
+    public void log(int level, Object obj1, Throwable exception) {
+        lastLog = (obj1 == null) ? "" : obj1.toString();
+        lastEx = exception;
+    }
+
+    public boolean check(int level) {
+        return true;
     }
 }
diff --git a/test-data/diagram/44501a.vsd b/test-data/diagram/44501a.vsd
new file mode 100755
index 0000000..7d9a3ce
--- /dev/null
+++ b/test-data/diagram/44501a.vsd
Binary files differ
diff --git a/test-data/diagram/44501b.vsd b/test-data/diagram/44501b.vsd
new file mode 100755
index 0000000..c8bd7a1
--- /dev/null
+++ b/test-data/diagram/44501b.vsd
Binary files differ
diff --git a/test-data/diagram/44501c.vsd b/test-data/diagram/44501c.vsd
new file mode 100644
index 0000000..51de23a
--- /dev/null
+++ b/test-data/diagram/44501c.vsd
Binary files differ
diff --git a/test-data/diagram/44501d.vsd b/test-data/diagram/44501d.vsd
new file mode 100755
index 0000000..2c1632e
--- /dev/null
+++ b/test-data/diagram/44501d.vsd
Binary files differ
diff --git a/test-data/diagram/44501e.vsd b/test-data/diagram/44501e.vsd
new file mode 100644
index 0000000..3ca5552
--- /dev/null
+++ b/test-data/diagram/44501e.vsd
Binary files differ
diff --git a/test-data/diagram/test.vsdx b/test-data/diagram/test.vsdx
new file mode 100644
index 0000000..1fa6903
--- /dev/null
+++ b/test-data/diagram/test.vsdx
Binary files differ
diff --git a/test-data/document/47304.doc b/test-data/document/47304.doc
new file mode 100644
index 0000000..d59d8d7
--- /dev/null
+++ b/test-data/document/47304.doc
Binary files differ
diff --git a/test-data/document/51921-Word-Crash067.doc b/test-data/document/51921-Word-Crash067.doc
new file mode 100644
index 0000000..dc8bfff
--- /dev/null
+++ b/test-data/document/51921-Word-Crash067.doc
Binary files differ
diff --git a/test-data/document/51921-Word-Crash067.docx b/test-data/document/51921-Word-Crash067.docx
new file mode 100644
index 0000000..12c27c8
--- /dev/null
+++ b/test-data/document/51921-Word-Crash067.docx
Binary files differ
diff --git a/test-data/document/52117.doc b/test-data/document/52117.doc
new file mode 100644
index 0000000..4f966c0
--- /dev/null
+++ b/test-data/document/52117.doc
Binary files differ
diff --git a/test-data/document/53379.doc b/test-data/document/53379.doc
new file mode 100644
index 0000000..5f1b3bd
--- /dev/null
+++ b/test-data/document/53379.doc
Binary files differ
diff --git a/test-data/document/56392.docx b/test-data/document/56392.docx
new file mode 100644
index 0000000..89a71ae
--- /dev/null
+++ b/test-data/document/56392.docx
Binary files differ
diff --git a/test-data/document/Numbering.docx b/test-data/document/Numbering.docx
index da0f325..d5605c9 100644
--- a/test-data/document/Numbering.docx
+++ b/test-data/document/Numbering.docx
Binary files differ
diff --git a/test-data/document/NumberingWOverrides.docx b/test-data/document/NumberingWOverrides.docx
new file mode 100644
index 0000000..48a7e2c
--- /dev/null
+++ b/test-data/document/NumberingWOverrides.docx
Binary files differ
diff --git a/test-data/document/au.edu.utas.www___data_assets_word_doc_0003_154335_International-Travel-Approval-Request-Form.doc b/test-data/document/au.edu.utas.www___data_assets_word_doc_0003_154335_International-Travel-Approval-Request-Form.doc
new file mode 100644
index 0000000..82d0041
--- /dev/null
+++ b/test-data/document/au.edu.utas.www___data_assets_word_doc_0003_154335_International-Travel-Approval-Request-Form.doc
Binary files differ
diff --git a/test-data/document/zero-length.docx b/test-data/document/zero-length.docx
new file mode 100644
index 0000000..eb34b47
--- /dev/null
+++ b/test-data/document/zero-length.docx
Binary files differ
diff --git a/test-data/hsmf/message_1979.msg b/test-data/hsmf/message_1979.msg
new file mode 100644
index 0000000..10083c8
--- /dev/null
+++ b/test-data/hsmf/message_1979.msg
Binary files differ
diff --git a/test-data/hsmf/message_1980.msg b/test-data/hsmf/message_1980.msg
new file mode 100644
index 0000000..bb29540
--- /dev/null
+++ b/test-data/hsmf/message_1980.msg
Binary files differ
diff --git a/test-data/hsmf/message_1981.msg b/test-data/hsmf/message_1981.msg
new file mode 100644
index 0000000..6833d54
--- /dev/null
+++ b/test-data/hsmf/message_1981.msg
Binary files differ
diff --git a/test-data/hsmf/message_extra_hyphen_submission_chunk.msg b/test-data/hsmf/message_extra_hyphen_submission_chunk.msg
new file mode 100644
index 0000000..3bcb8d3
--- /dev/null
+++ b/test-data/hsmf/message_extra_hyphen_submission_chunk.msg
Binary files differ
diff --git a/test-data/hsmf/message_normal_submission_chunk.msg b/test-data/hsmf/message_normal_submission_chunk.msg
new file mode 100644
index 0000000..bb15d27
--- /dev/null
+++ b/test-data/hsmf/message_normal_submission_chunk.msg
Binary files differ
diff --git a/test-data/openxml4j/OPCCompliance_NoCoreProperties.xlsx b/test-data/openxml4j/OPCCompliance_NoCoreProperties.xlsx
new file mode 100644
index 0000000..fa1049c
--- /dev/null
+++ b/test-data/openxml4j/OPCCompliance_NoCoreProperties.xlsx
Binary files differ
diff --git a/test-data/poifs/only-zero-byte-streams.ole2 b/test-data/poifs/only-zero-byte-streams.ole2
new file mode 100644
index 0000000..c1b8429
--- /dev/null
+++ b/test-data/poifs/only-zero-byte-streams.ole2
Binary files differ
diff --git a/test-data/poifs/unknown_properties.msg b/test-data/poifs/unknown_properties.msg
new file mode 100644
index 0000000..2c76df9
--- /dev/null
+++ b/test-data/poifs/unknown_properties.msg
Binary files differ
diff --git a/test-data/slideshow/54332a.ppt b/test-data/slideshow/54332a.ppt
new file mode 100644
index 0000000..ebdedf5
--- /dev/null
+++ b/test-data/slideshow/54332a.ppt
Binary files differ
diff --git a/test-data/slideshow/54332b.ppt b/test-data/slideshow/54332b.ppt
new file mode 100644
index 0000000..41f20fa
--- /dev/null
+++ b/test-data/slideshow/54332b.ppt
Binary files differ
diff --git a/test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx b/test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx
new file mode 100644
index 0000000..ca9d791
--- /dev/null
+++ b/test-data/slideshow/ae.ac.uaeu.faculty_nafaachbili_GeomLec1.pptx
Binary files differ
diff --git a/test-data/slideshow/at.ecodesign.www_downloads_Vertiefungsvortrag_elektronik.pptx b/test-data/slideshow/at.ecodesign.www_downloads_Vertiefungsvortrag_elektronik.pptx
new file mode 100644
index 0000000..0578862
--- /dev/null
+++ b/test-data/slideshow/at.ecodesign.www_downloads_Vertiefungsvortrag_elektronik.pptx
Binary files differ
diff --git a/test-data/slideshow/bug57820-initTableNullRefrenceException.ppt b/test-data/slideshow/bug57820-initTableNullRefrenceException.ppt
new file mode 100644
index 0000000..e7525f9
--- /dev/null
+++ b/test-data/slideshow/bug57820-initTableNullRefrenceException.ppt
Binary files differ
diff --git a/test-data/spreadsheet/49423.xls b/test-data/spreadsheet/49423.xls
new file mode 100644
index 0000000..3d8524c
--- /dev/null
+++ b/test-data/spreadsheet/49423.xls
Binary files differ
diff --git a/test-data/spreadsheet/53109.xls b/test-data/spreadsheet/53109.xls
new file mode 100644
index 0000000..08b4dfe
--- /dev/null
+++ b/test-data/spreadsheet/53109.xls
Binary files differ
diff --git a/test-data/spreadsheet/56295.xlsx b/test-data/spreadsheet/56295.xlsx
new file mode 100644
index 0000000..d929d99
--- /dev/null
+++ b/test-data/spreadsheet/56295.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/56325a.xls b/test-data/spreadsheet/56325a.xls
new file mode 100644
index 0000000..a1e52cb
--- /dev/null
+++ b/test-data/spreadsheet/56325a.xls
Binary files differ
diff --git a/test-data/spreadsheet/56574.xlsx b/test-data/spreadsheet/56574.xlsx
new file mode 100644
index 0000000..9cce54c
--- /dev/null
+++ b/test-data/spreadsheet/56574.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/57163.xls b/test-data/spreadsheet/57163.xls
new file mode 100644
index 0000000..402c954
--- /dev/null
+++ b/test-data/spreadsheet/57163.xls
Binary files differ
diff --git a/test-data/spreadsheet/57423.xlsx b/test-data/spreadsheet/57423.xlsx
new file mode 100644
index 0000000..54c65be
--- /dev/null
+++ b/test-data/spreadsheet/57423.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/57826.xlsx b/test-data/spreadsheet/57826.xlsx
new file mode 100644
index 0000000..ccf2dc3
--- /dev/null
+++ b/test-data/spreadsheet/57826.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/57828.xlsx b/test-data/spreadsheet/57828.xlsx
new file mode 100644
index 0000000..c750a09
--- /dev/null
+++ b/test-data/spreadsheet/57828.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/57893-many-merges.xlsx b/test-data/spreadsheet/57893-many-merges.xlsx
new file mode 100644
index 0000000..572dfec
--- /dev/null
+++ b/test-data/spreadsheet/57893-many-merges.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/NewStyleConditionalFormattings.xls b/test-data/spreadsheet/NewStyleConditionalFormattings.xls
new file mode 100644
index 0000000..fdb241b
--- /dev/null
+++ b/test-data/spreadsheet/NewStyleConditionalFormattings.xls
Binary files differ
diff --git a/test-data/spreadsheet/NewStyleConditionalFormattings.xlsx b/test-data/spreadsheet/NewStyleConditionalFormattings.xlsx
new file mode 100644
index 0000000..93c034f
--- /dev/null
+++ b/test-data/spreadsheet/NewStyleConditionalFormattings.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/SampleSS.strict.xlsx b/test-data/spreadsheet/SampleSS.strict.xlsx
new file mode 100644
index 0000000..6bf1936
--- /dev/null
+++ b/test-data/spreadsheet/SampleSS.strict.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/SimpleNormal.xlsx b/test-data/spreadsheet/SimpleNormal.xlsx
new file mode 100644
index 0000000..35378c7
--- /dev/null
+++ b/test-data/spreadsheet/SimpleNormal.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/SimpleStrict.xlsx b/test-data/spreadsheet/SimpleStrict.xlsx
new file mode 100644
index 0000000..7ed3e45
--- /dev/null
+++ b/test-data/spreadsheet/SimpleStrict.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls b/test-data/spreadsheet/ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls
new file mode 100644
index 0000000..5554ab9
--- /dev/null
+++ b/test-data/spreadsheet/ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls
Binary files differ
diff --git a/test-data/spreadsheet/com.aida-tour.www_SPO_files_maldives%20august%20october.xls b/test-data/spreadsheet/com.aida-tour.www_SPO_files_maldives%20august%20october.xls
new file mode 100644
index 0000000..90b0bd6
--- /dev/null
+++ b/test-data/spreadsheet/com.aida-tour.www_SPO_files_maldives%20august%20october.xls
Binary files differ
diff --git a/test-data/spreadsheet/protected_passtika.xlsx b/test-data/spreadsheet/protected_passtika.xlsx
new file mode 100644
index 0000000..deea286
--- /dev/null
+++ b/test-data/spreadsheet/protected_passtika.xlsx
Binary files differ
diff --git a/test-data/spreadsheet/sample.strict.xlsx b/test-data/spreadsheet/sample.strict.xlsx
new file mode 100644
index 0000000..9c6c8f1
--- /dev/null
+++ b/test-data/spreadsheet/sample.strict.xlsx
Binary files differ