Index: test/layoutengine/standard-testcases/markers_3.xml
===================================================================
--- test/layoutengine/standard-testcases/markers_3.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/markers_3.xml	(revision )
@@ -55,7 +55,7 @@
           </fo:block>
         </fo:static-content>
         <fo:flow flow-name="xsl-region-body">
-          <fo:block>
+          <fo:block widows="1" orphans="1">
             <fo:block font-size="14pt" font-weight="bold">
               <fo:marker marker-class-name="PAGE">[PAGE]</fo:marker>
               <fo:marker marker-class-name="PS">[PS]</fo:marker>
@@ -96,7 +96,7 @@
           </fo:block>
         </fo:static-content>
         <fo:flow flow-name="xsl-region-body">
-          <fo:block>
+          <fo:block widows="1" orphans="1">
             <fo:block>sometext</fo:block>
             <fo:block>sometext</fo:block>
             <fo:block>sometext</fo:block>
Index: test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml
===================================================================
--- test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml	(revision 992029)
+++ test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml	(revision )
@@ -45,7 +45,7 @@
             <fo:table-body>
               <fo:table-row>
                 <fo:table-cell>
-                  <fo:block>
+                  <fo:block widows="1" orphans="1">
                     <fo:block id="before_break">Block before the page break.</fo:block>
                     <fo:block id="after_break">Block after the page break.</fo:block>
                   </fo:block>
Index: test/layoutengine/standard-testcases/block_padding_2.xml
===================================================================
--- test/layoutengine/standard-testcases/block_padding_2.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_padding_2.xml	(revision )
@@ -49,16 +49,7 @@
       <penalty w="0" p="INF"/>
       <glue w="30000"/>
       
-      <box w="14400"/>
+      <box w="14400"/>      
-      
-      <penalty w="0" p="INF"/>
-      <glue w="30000"/> <!-- w="30000" is for the padding-after -->
-      <penalty w="0" p="0"/>
-      <glue w="-60000"/> <!-- difference between break and no-break situation -->
-      <box w="0"/>
-      <penalty w="0" p="INF"/>
-      <glue w="30000"/> <!-- w="30000" is for the padding-before -->
-      
       <box w="14400"/>
       
       <penalty w="0" p="INF"/>
@@ -90,15 +81,6 @@
       <glue w="30000"/>
       
       <box w="14400"/>
-
-      <penalty w="0" p="INF"/>
-      <glue w="30000"/>
-      <penalty w="0" p="0"/>
-      <glue w="-60000"/>
-      <box w="0"/>
-      <penalty w="0" p="INF"/>
-      <glue w="30000"/>
-      
       <box w="14400"/>
       
       <box w="0"/>
Index: test/layoutengine/standard-testcases/inline_block_nested_4.xml
===================================================================
--- test/layoutengine/standard-testcases/inline_block_nested_4.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/inline_block_nested_4.xml	(revision )
@@ -52,19 +52,13 @@
   <checks>
     <element-list category="breaker">
       <box w="12000"/>
-      <penalty w="0" p="0"/>
       <box w="12000"/>
-      <penalty w="0" p="0"/>
       <box w="12000"/>
       <penalty w="0" p="0"/>
       <box w="12000"/>
-      <penalty w="0" p="0"/>
       <box w="12000"/>
-      <penalty w="0" p="0"/>
       <box w="12000"/>
-      <penalty w="0" p="1000"/>
-      <glue w="0"/>
-      <penalty w="0" p="-1000"/>
+      <skip>3</skip>
     </element-list>
     
     <!-- first block -->
Index: test/layoutengine/standard-testcases/block_border_bug43917.xml
===================================================================
--- test/layoutengine/standard-testcases/block_border_bug43917.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_border_bug43917.xml	(revision )
@@ -55,7 +55,6 @@
       <glue w="1000"/> <!-- border-before -->
       
       <box w="14400"/> <!-- Line 1 -->
-      <penalty w="0" p="0"/> <!--SpaceHandlingBreakPosition-->
       <box w="14400"/> <!-- Line 2 -->
       
       <penalty w="0" p="INF"/>
@@ -70,7 +69,6 @@
       <glue w="1000"/> <!-- border-before -->
       
       <box w="14400"/> <!-- Line 1 -->
-      <penalty w="0" p="0"/> <!--SpaceHandlingBreakPosition-->
       <box w="14400"/> <!-- Line 2 -->
       
       <penalty w="0" p="INF"/>
Index: test/layoutengine/standard-testcases/inline_block_nested_6.xml
===================================================================
--- test/layoutengine/standard-testcases/inline_block_nested_6.xml	(revision 807014)
+++ test/layoutengine/standard-testcases/inline_block_nested_6.xml	(revision )
@@ -49,14 +49,14 @@
   </fo>
   <checks>
     <element-list category="breaker">
-      <skip>5</skip>
+      <skip>3</skip>
       <!-- penalty between blocks b11 and b12, set by InlineLM in b1 -->
       <penalty w="0" p="0"/>
       <skip>5</skip>
       <!-- penalty between blocks b21 and b22, set by InlineLM in b2 -->
       <!-- keep-together.within-page="always" -->
       <penalty w="0" p="1000"/>
-      <skip>3</skip>
+      <skip>5</skip>
       <!-- penalty between blocks b31 and b32, set by InlineLM in b3 -->
       <!-- keep-with-next.within-page="always" -->
       <penalty w="0" p="1000"/>
Index: test/layoutengine/standard-testcases/table_border-collapse_separate_conditionals.xml
===================================================================
--- test/layoutengine/standard-testcases/table_border-collapse_separate_conditionals.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/table_border-collapse_separate_conditionals.xml	(revision )
@@ -48,7 +48,7 @@
                   padding-after.conditionality="retain"
                   padding-before.length="2pt"
                   padding-before.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
@@ -60,7 +60,7 @@
                   border-before-width.conditionality="retain"
                   border-after-width.length="2pt"
                   border-after-width.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
@@ -87,7 +87,7 @@
                   border-before-width.conditionality="retain"
                   padding-after.length="5pt"
                   padding-after.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
@@ -99,7 +99,7 @@
                   border-after-width.conditionality="retain"
                   padding-before.length="7pt"
                   padding-before.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
@@ -130,7 +130,7 @@
                   padding-before.conditionality="retain"
                   padding-after.length="1pt"
                   padding-after.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
@@ -138,7 +138,7 @@
                   </fo:block>
                 </fo:table-cell>
                 <fo:table-cell border="4pt solid blue" padding="2pt">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
@@ -165,7 +165,7 @@
                   border-after-width.conditionality="retain"
                   padding-after.length="9pt"
                   padding-after.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
@@ -177,7 +177,7 @@
                   border-before-width.conditionality="retain"
                   padding-before.length="11pt"
                   padding-before.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
@@ -201,7 +201,7 @@
             <fo:table-column column-width="proportional-column-width(1)" number-columns-repeated="2"/>
             <fo:table-body>
               <fo:table-row>
-                <fo:table-cell border="2pt solid blue">
+                <fo:table-cell border="2pt solid blue" widows="1" orphans="1">
                   <fo:block>Cell 1.1</fo:block>
                   <fo:block>Cell 1.1</fo:block>
                   <fo:block>Cell 1.1</fo:block>
Index: test/layoutengine/standard-testcases/inline_block-level_nested_1.xml
===================================================================
--- test/layoutengine/standard-testcases/inline_block-level_nested_1.xml	(revision 815383)
+++ test/layoutengine/standard-testcases/inline_block-level_nested_1.xml	(revision )
@@ -77,23 +77,17 @@
   <checks>
     <element-list category="breaker">
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       <penalty w="0" p="0"/>
       <glue w="6000" aux="true"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       <penalty w="0" p="0"/>
       <glue w="6000" aux="true"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       <skip>3</skip>
     </element-list>
Index: test/layoutengine/standard-testcases/table_border-collapse_collapse_conditionals.xml
===================================================================
--- test/layoutengine/standard-testcases/table_border-collapse_collapse_conditionals.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/table_border-collapse_collapse_conditionals.xml	(revision )
@@ -43,7 +43,7 @@
             <fo:table-body>
               <fo:table-row border="5pt solid red">
                 <fo:table-cell border="7pt solid blue" padding="2pt">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.1</fo:block>
                     <fo:block>Cell 1.1</fo:block>
                   </fo:block>
@@ -54,7 +54,7 @@
                   border-before-width.conditionality="retain"
                   padding-after.length="7pt"
                   padding-after.conditionality="retain">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
                     <fo:block>Cell 1.2</fo:block>
@@ -66,7 +66,7 @@
                 border-before-width.length="5pt"
                 border-before-width.conditionality="retain">
                 <fo:table-cell border="4pt solid green" padding="2pt">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 2.1</fo:block>
                     <fo:block>Cell 2.1</fo:block>
                   </fo:block>
@@ -105,7 +105,7 @@
                 border-before-width.length="5pt"
                 border-before-width.conditionality="retain">
                 <fo:table-cell border="4pt solid green" padding="2pt">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 2.1</fo:block>
                     <fo:block>Cell 2.1</fo:block>
                   </fo:block>
@@ -115,7 +115,7 @@
                 border-before-width.length="5pt"
                 border-before-width.conditionality="retain">
                 <fo:table-cell border="4pt solid green" padding="2pt">
-                  <fo:block background-color="yellow">
+                  <fo:block background-color="yellow" widows="1" orphans="1">
                     <fo:block>Cell 3.1</fo:block>
                     <fo:block>Cell 3.1</fo:block>
                   </fo:block>
Index: test/layoutengine/standard-testcases/wrapper_inline_block.xml
===================================================================
--- test/layoutengine/standard-testcases/wrapper_inline_block.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/wrapper_inline_block.xml	(revision )
@@ -40,9 +40,7 @@
     <!-- Just check if this really results in 3 lines. -->
     <element-list category="breaker">
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       <skip>3</skip>
     </element-list>
Index: test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml
===================================================================
--- test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml	(revision 827047)
+++ test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml	(revision )
@@ -53,7 +53,7 @@
             <fo:table-body>
               <fo:table-row>
                 <fo:table-cell>
-                  <fo:block>
+                  <fo:block widows="1" orphans="1">
                     <fo:block>Before page break</fo:block>
                     <fo:block>After page break</fo:block>
                   </fo:block>
@@ -70,7 +70,7 @@
             <fo:table-body>
               <fo:table-row>
                 <fo:table-cell>
-                  <fo:block>
+                  <fo:block widows="1" orphans="1">
                     <fo:block>Before page break</fo:block>
                     <fo:block>After page break</fo:block>
                   </fo:block>
@@ -122,7 +122,7 @@
             <fo:table-body>
               <fo:table-row>
                 <fo:table-cell>
-                  <fo:block>
+                  <fo:block widows="1" orphans="1">
                     <fo:block>Before page break</fo:block>
                     <fo:block>After page break</fo:block>
                   </fo:block>
Index: test/layoutengine/standard-testcases/block_space-before_space-after_4.xml
===================================================================
--- test/layoutengine/standard-testcases/block_space-before_space-after_4.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_space-before_space-after_4.xml	(revision )
@@ -48,16 +48,14 @@
       <penalty w="0" p="INF"/>
       <glue w="5000"/>
       <box w="10000"/>
-      <penalty w="0" p="0"/>
-      
       <box w="10000"/>
       <penalty w="0" p="0"/>
 
-      <!-- skip two more lines -->
+      <!-- skip one line -->
       <skip>2</skip>
-      <skip>2</skip>
       
       <box w="10000"/>
+      <box w="10000"/>
       
       <skip>3</skip>
     </element-list>
@@ -69,8 +67,8 @@
     <eval expected="1" xpath="count(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block)"/>
     <eval expected="1" xpath="count(//pageViewport[@nr=3]/page/regionViewport/regionBody/mainReference/span/flow/block)"/>
     <eval expected="2" xpath="count(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block)"/>
-    <eval expected="2" xpath="count(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block)"/>
-    <eval expected="1" xpath="count(//pageViewport[@nr=3]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block)"/>
+    <eval expected="1" xpath="count(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block)"/>
+    <eval expected="2" xpath="count(//pageViewport[@nr=3]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block)"/>
     
   </checks>
 </testcase>
Index: test/layoutengine/standard-testcases/markers_2.xml
===================================================================
--- test/layoutengine/standard-testcases/markers_2.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/markers_2.xml	(revision )
@@ -55,7 +55,7 @@
           </fo:block-container>
         </fo:static-content>
         <fo:flow flow-name="xsl-region-body">
-          <fo:block>
+          <fo:block widows="1" orphans="1">
             <fo:marker marker-class-name="part1">
               <fo:block background-color="black" color="white" text-align="center">1</fo:block>
             </fo:marker>
@@ -68,7 +68,7 @@
             <fo:block>text1</fo:block>
             <fo:block>text1</fo:block>
           </fo:block>
-          <fo:block>
+          <fo:block widows="1" orphans="1">
             <fo:marker marker-class-name="part2">
               <fo:block background-color="black" color="white" text-align="center">2</fo:block>
             </fo:marker>
@@ -78,7 +78,7 @@
             <fo:block>text2</fo:block>
             <fo:block>text2</fo:block>
           </fo:block>
-          <fo:block>
+          <fo:block widows="1" orphans="1">
             <fo:marker marker-class-name="part3">
               <fo:block background-color="black" color="white" text-align="center">3</fo:block>
             </fo:marker>
Index: test/layoutengine/standard-testcases/block_space-before_space-after_7.xml
===================================================================
--- test/layoutengine/standard-testcases/block_space-before_space-after_7.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_space-before_space-after_7.xml	(revision )
@@ -47,7 +47,8 @@
       <glue w="7000"/>
       <box w="14400"/>
       
-      <penalty w="0" p="0"/>
+      <box w="0"/>
+      <penalty w="0" p="INF"/>
       
       <glue w="6000"/>
       <box w="14400"/>
Index: test/layoutengine/standard-testcases/region-body_column-count_bug37828.xml
===================================================================
--- test/layoutengine/standard-testcases/region-body_column-count_bug37828.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/region-body_column-count_bug37828.xml	(revision )
@@ -62,9 +62,9 @@
     <eval expected="57600" xpath="//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span[2]/flow[1]/@bpd"/>
     <eval expected="57600" xpath="//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span[2]/flow[2]/@bpd"/>
 
-    <eval expected="14400" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/@bpd"/>
-    <eval expected="14400" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/flow[1]/@bpd"/>
-    <eval expected="14400" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/flow[2]/@bpd"/>
+    <eval expected="28800" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/@bpd"/>
+    <eval expected="28800" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/flow[1]/@bpd"/>
+    <eval expected="0" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[1]/flow[2]/@bpd"/>
     <eval expected="14400" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span[2]/@bpd"/>
   </checks>
 </testcase>
Index: test/layoutengine/standard-testcases/block_space-before_space-after_6.xml
===================================================================
--- test/layoutengine/standard-testcases/block_space-before_space-after_6.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_space-before_space-after_6.xml	(revision )
@@ -33,7 +33,7 @@
       <fo:page-sequence master-reference="normal" id="ex1">
         <fo:flow flow-name="xsl-region-body">
           <fo:block>first line</fo:block>
-          <fo:block space-before="10pt">
+          <fo:block space-before="10pt" orphans="1" widows="1">
             <fo:block>before break</fo:block>
             <fo:block>after break</fo:block>
           </fo:block>
@@ -42,7 +42,8 @@
       <fo:page-sequence master-reference="normal" id="ex2">
         <fo:flow flow-name="xsl-region-body">
           <fo:block>first line</fo:block>
-          <fo:block space-before="10pt" space-before.conditionality="retain">
+          <fo:block space-before="10pt" space-before.conditionality="retain"
+                    orphans="1" widows="1">
             <fo:block>before break</fo:block>
             <fo:block>after break</fo:block>
           </fo:block>
Index: test/layoutengine/standard-testcases/flow_changing-ipd_last-page.xml
===================================================================
--- test/layoutengine/standard-testcases/flow_changing-ipd_last-page.xml	(revision 915406)
+++ test/layoutengine/standard-testcases/flow_changing-ipd_last-page.xml	(revision )
@@ -45,7 +45,7 @@
       <fo:page-sequence master-reference="pages" font-size="8pt" line-height="10pt">
         <fo:flow flow-name="xsl-region-body" text-align="justify">
           <fo:block space-after="140pt">First block</fo:block>
-          <fo:block id="surrounding">
+          <fo:block id="surrounding" widows="1" orphans="1">
             <fo:block id="before">Block before the page break.</fo:block>
             <fo:block id="after">Block after the page break.</fo:block>
           </fo:block>
Index: test/layoutengine/standard-testcases/inline_block_nested_1.xml
===================================================================
--- test/layoutengine/standard-testcases/inline_block_nested_1.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/inline_block_nested_1.xml	(revision )
@@ -39,9 +39,7 @@
   <checks>
     <element-list category="breaker">
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="0" aux="true"/> <!-- this is from the empty block -->
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       <skip>3</skip>
     </element-list>
Index: test/layoutengine/standard-testcases/block_space-before_space-after_bug38102.xml
===================================================================
--- test/layoutengine/standard-testcases/block_space-before_space-after_bug38102.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_space-before_space-after_bug38102.xml	(revision )
@@ -113,7 +113,8 @@
     <element-list category="breaker" id="block">
       <box w="14400"/>
       
-      <penalty w="0" p="0"/>
+      <box w="0"/>
+      <penalty w="0" p="INF"/>
       
       <glue w="16000" y="0" z="0"/>
       <box w="14400"/>
@@ -127,7 +128,6 @@
       <box w="14400"/>
       <penalty w="0" p="0"/>
       <box w="14400"/>
-      <penalty w="0" p="0"/>
       <box w="14400"/>
       
       <skip>3</skip>
Index: test/layoutengine/standard-testcases/block_space-before_space-after_9a.xml
===================================================================
--- test/layoutengine/standard-testcases/block_space-before_space-after_9a.xml	(revision 627324)
+++ test/layoutengine/standard-testcases/block_space-before_space-after_9a.xml	(revision )
@@ -59,9 +59,7 @@
     <element-list category="breaker" index="1">
       <box w="0"/> <!-- SpaceHandlingPosition -->
       
-      <box w="0"/> <!-- empty block used to cause the break-before -->
+      <box w="0"/> <!-- empty block used to cause the break-before -->      
-      <penalty w="0" p="0"/>
-      
       <box w="14400"/>
       
       <box w="0"/>
Index: src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java	(revision 1073116)
+++ src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java	(revision )
@@ -66,6 +66,9 @@
     private MinOptMax effSpaceBefore;
     private MinOptMax effSpaceAfter;
 
+    private int orphans = 2;
+    private int widows = 2;
+
     /**
      * Creates a new BlockLayoutManager.
      * @param inBlock the block FO object to create the layout manager for.
@@ -97,6 +100,8 @@
                                     .getOptimum(this).getLength().getValue(this);
         adjustedSpaceAfter = fo.getCommonMarginBlock().spaceAfter.getSpace()
                                     .getOptimum(this).getLength().getValue(this);
+        orphans = fo.getOrphans();
+        widows = fo.getWidows();
     }
 
     /** {@inheritDoc} */
@@ -110,10 +115,76 @@
     public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
             Position restartPosition, LayoutManager restartAtLM) {
         resetSpaces();
-        return super.getNextKnuthElements(
+
+        List<ListElement> contentList = super.getNextKnuthElements(
                 context, alignment, lmStack, restartPosition, restartAtLM);
+
+        if (!this.hasNextChildLM()) {
+            // handle widows
+            int boxCount = 0;
+            ListElement current, last = null;
+            for (ListIterator<ListElement> it = contentList.listIterator(contentList.size());
+                    it.hasPrevious();) {
+                current = it.previous();
+                if (current.isBox() && !((KnuthBox) current).isAuxiliary()) {
+                    // non-auxiliary box => assume a 'line' and increase boxCount
+                    boxCount++;
+                    if (boxCount >= widows) {
+                        break;
-    }
+                    }
+                } else if (current.isGlue()) {
+                    if (it.hasPrevious() && it.previous().isBox()) {
+                        // return to current
+                        it.next();
+                        it.next();
+                        KnuthGlue glue = (KnuthGlue)current;
+                        if (glue.getShrink() == 0 && glue.getStretch() == 0) {
+                            // non-stretchable glue => convert to auxiliary box
+                            it.set(new KnuthBox(glue.getWidth(), glue.getPosition(), true));
+                        } else {
+                            // stretchable glue => convert to auxiliary box
+                            it.previous();
+                            it.previous();
+                            it.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, true));
+                            it.previous();
+                        }
+                    }
+                } else if (current.isPenalty() || current instanceof BreakElement
+                            && !current.isForcedBreak()) {
+                    if (last != null && last.isBox()
+                            && it.hasPrevious() && it.previous().isBox()) {
+                        // return to current
+                        it.next();
+                        it.next();
+                        // penalty or BreakElement in between two boxes => remove
+                        it.remove();
+                    } else {
+                        it.next();
+                        if (current.isPenalty()) {
+                            KnuthPenalty penalty = (KnuthPenalty)current;
+                            //Convert penalty to break inhibitor
+                            if (penalty.getPenalty() < KnuthPenalty.INFINITE) {
+                                it.set(new KnuthPenalty(penalty.getWidth(), KnuthPenalty.INFINITE,
+                                        penalty.isPenaltyFlagged(), penalty.getPosition(),
+                                        penalty.isAuxiliary()));
+                            }
+                        } else {
+                            // a BreakElement
+                            BreakElement breakEl = (BreakElement)current;
+                            if (breakEl.getPenaltyValue() < KnuthPenalty.INFINITE) {
+                                breakEl.setPenaltyValue(KnuthPenalty.INFINITE);
+                            }
+                        }
+                        it.previous();
+                    }
+                }
+                last = current;
+            }
+        }
 
+        return contentList;
+    }
+
     /**
      * Overridden to take into account that the childLM may be the block's
      * {@link LineLayoutManager}.
@@ -132,25 +203,117 @@
             // nop; will have been properly set by makeChildLayoutContext()
         }
 
-        if (childLM == this.childLMs.get(0)) {
+        boolean isFirst = childLM == this.childLMs.get(0);
+        if (isFirst) {
             childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
             //Handled already by the parent (break collapsing, see above)
         }
 
+        List<ListElement> childElements;
         if (lmStack == null) {
-            return childLM.getNextKnuthElements(childLC, alignment);
+            childElements = childLM.getNextKnuthElements(childLC, alignment);
         } else {
             if (childLM instanceof LineLayoutManager) {
                 assert (restartPosition instanceof LeafPosition);
-                return ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
+                childElements = ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
                         (LeafPosition) restartPosition);
             } else {
-                return childLM.getNextKnuthElements(childLC, alignment,
+                childElements = childLM.getNextKnuthElements(childLC, alignment,
                         lmStack, restartPosition, restartAtLM);
             }
         }
+
+        if (isFirst) {
+            // handle orphans
+            int boxCount = 0;
+            ListElement current, previous = null;
+            for (ListIterator<ListElement> it = childElements.listIterator(); it.hasNext();) {
+                current = it.next();
+                if (current.isBox() && !((KnuthBox) current).isAuxiliary()) {
+                    // non-auxiliary box => assume a 'line' and increase boxCount
+                    boxCount++;
+                    if (boxCount >= orphans) {
+                        break;
-    }
+                    }
+                } else if (current.isGlue()) {
+                    if (previous != null && previous.isBox()) {
+                        KnuthGlue glue = (KnuthGlue) current;
+                        if (glue.getStretch() == 0 && glue.getShrink() == 0) {
+                            // non-stretchable glue => replace with a box of the same width
+                            it.set(new KnuthBox(glue.getWidth(), glue.getPosition(), true));
+                        } else {
+                            // stretchable glue => add break-inhibitor
+                            it.previous();
+                            it.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, true));
+                            it.next();
+                        }
+                    }
+                } else if (current.isPenalty() || current instanceof BreakElement
+                            && !current.isForcedBreak()) {
+                    if (previous != null && previous.isBox()
+                            && it.hasNext() && it.next().isBox()) {
+                        // penalty or BreakElement in between boxes => remove
+                        it.previous();
+                        it.previous();
+                        it.remove();
+                    } else {
+                        it.previous();
+                        it.previous();
+                        if (current.isPenalty()) {
+                            KnuthPenalty penalty = (KnuthPenalty)current;
+                            //Convert penalty to break inhibitor
+                            if (penalty.getPenalty() < KnuthPenalty.INFINITE) {
+                                it.set(new KnuthPenalty(penalty.getWidth(), KnuthPenalty.INFINITE,
+                                        penalty.isPenaltyFlagged(), penalty.getPosition(),
+                                        penalty.isAuxiliary()));
+                            }
+                        } else {
+                            // a BreakElement
+                            BreakElement breakEl = (BreakElement)current;
+                            if (breakEl.getPenaltyValue() < KnuthPenalty.INFINITE) {
+                                breakEl.setPenaltyValue(KnuthPenalty.INFINITE);
+                            }
+                        }
+                    }
+                }
+                previous = current;
+            }
+        }
 
+        return childElements;
+    }
+
+    /**
+     * Overridden to deal with a special case for the "orphans" property.
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addInBetweenBreak(List<ListElement> contentList, LayoutContext parentLC, LayoutContext childLC) {
+
+        if (this.childLMs.size() > 1 &&
+                this.curChildLM == this.childLMs.get(1)) {
+            // special case: second childLM; if the first childLM did not produce enough
+            // lines to satisfy this LM's orphans constraint, avoid adding a break possibility
+            boolean orphansSatisfied = false;
+            int boxCount = 0;
+            for (ListElement el : contentList) {
+                if (el.isBox() && !((KnuthBox) el).isAuxiliary()) {
+                    boxCount++;
+                    if (boxCount >= orphans) {
+                        orphansSatisfied = true;
+                        break;
+                    }
+                }
+            }
+
+            if (!orphansSatisfied) {
+                return;
+            }
+        }
+
+        super.addInBetweenBreak(contentList, parentLC, childLC);
+    }
+
     private void resetSpaces() {
         this.discardBorderBefore = false;
         this.discardBorderAfter = false;
Index: src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(revision 1067698)
+++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(revision )
@@ -155,7 +155,7 @@
     private final int follow;
     private AlignmentContext alignmentContext;
 
-    private List knuthParagraphs;
+    private List<KnuthSequence> knuthParagraphs;
 
     private LineLayoutPossibilities lineLayouts;
     private LineLayoutPossibilities[] lineLayoutsList;
@@ -400,7 +400,7 @@
             // true if this line contains only zero-height, auxiliary boxes
             // and the actual line width is 0; in this case, the line "collapses"
             // i.e. the line area will have bpd = 0
-            boolean bZeroHeightLine = (difference == ipd);
+            boolean isZeroHeightLine = (difference == ipd);
 
             // if line-stacking-strategy is "font-height", the line height
             // is not affected by its content
@@ -436,9 +436,9 @@
                             }
                             lastAC = ac;
                         }
-                        if (bZeroHeightLine
+                        if (isZeroHeightLine
                             && (!element.isAuxiliary() || ac != null && ac.getHeight() > 0)) {
-                            bZeroHeightLine = false;
+                            isZeroHeightLine = false;
                         }
                     }
                 }
@@ -450,7 +450,7 @@
 
             constantLineHeight = lineLead + lineFollow;
 
-            if (bZeroHeightLine) {
+            if (isZeroHeightLine) {
                 return new LineBreakPosition(thisLLM,
                                              knuthParagraphs.indexOf(par),
                                              firstElementIndex, lastElementIndex,
@@ -580,7 +580,7 @@
         //PHASE 1: Create Knuth elements
         if (knuthParagraphs == null) {
             // it's the first time this method is called
-            knuthParagraphs = new ArrayList();
+            knuthParagraphs = new ArrayList<KnuthSequence>();
 
             // here starts Knuth's algorithm
             collectInlineKnuthElements(context);
@@ -612,12 +612,10 @@
             LeafPosition restartPosition) {
         log.trace("Restarting line breaking from index " + restartPosition.getIndex());
         int parIndex = restartPosition.getLeafPos();
-        Paragraph paragraph = (Paragraph) knuthParagraphs.get(parIndex);
-        for (int i = 0; i <= restartPosition.getIndex(); i++) {
-            paragraph.remove(0);
-        }
-        Iterator iter = paragraph.iterator();
-        while (iter.hasNext() && !((KnuthElement) iter.next()).isBox()) {
+        KnuthSequence paragraph = knuthParagraphs.get(parIndex);
+        paragraph.subList(0, restartPosition.getIndex()).clear();
+        Iterator<KnuthElement> iter = paragraph.iterator();
+        while (iter.hasNext() && !iter.next().isBox()) {
             iter.remove();
         }
         if (!iter.hasNext()) {
@@ -650,8 +648,8 @@
 
         Paragraph lastPar = null;
 
-        InlineLevelLayoutManager curLM;
-        while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
+        InlineLevelLayoutManager curLM = (InlineLevelLayoutManager) getChildLM();
+        while (curLM != null) {
             List inlineElements = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
             if (inlineElements == null || inlineElements.size() == 0) {
                 /* curLM.getNextKnuthElements() returned null or an empty list;
@@ -748,7 +746,9 @@
                     }
                 }
             } // end of loop over returnedList
+            curLM = (InlineLevelLayoutManager) getChildLM();
         }
+
         if (lastPar != null) {
             lastPar.endParagraph();
             ElementListObserver.observe(lastPar, "line", fobj.getId());
@@ -765,13 +765,13 @@
      * @param context the layout context
      * @return a list of Knuth elements representing broken lines
      */
-    private List createLineBreaks(int alignment, LayoutContext context) {
+    private List<ListElement> createLineBreaks(int alignment, LayoutContext context) {
         // find the optimal line breaking points for each paragraph
-        Iterator paragraphsIterator = knuthParagraphs.iterator();
+        Iterator<KnuthSequence> paragraphsIterator = knuthParagraphs.iterator();
         lineLayoutsList = new LineLayoutPossibilities[knuthParagraphs.size()];
         LineLayoutPossibilities llPoss;
         for (int i = 0; paragraphsIterator.hasNext(); i++) {
-            KnuthSequence seq = (KnuthSequence) paragraphsIterator.next();
+            KnuthSequence seq = paragraphsIterator.next();
             if (!seq.isInlineSequence()) {
                 // This set of line layout possibilities does not matter;
                 // we only need an entry in lineLayoutsList.
@@ -807,7 +807,7 @@
                                         lineHeight.getValue(this), lead, follow,
                                         (knuthParagraphs.indexOf(currPar) == 0),
                                         hyphenationLadderCount.getEnum() == EN_NO_LIMIT
-                                        ? 0 : hyphenationLadderCount.getValue(),
+                                            ? 0 : hyphenationLadderCount.getValue(),
                                         this);
         alg.setConstantLineWidth(ipd);
         boolean canWrap = (wrapOption != EN_NO_WRAP);
@@ -873,12 +873,15 @@
      * @param context the layout context
      * @return the newly built element list
      */
-    private List postProcessLineBreaks(int alignment, LayoutContext context) {
+    private List<ListElement> postProcessLineBreaks(int alignment, LayoutContext context) {
 
         List<ListElement> returnList = new LinkedList<ListElement>();
 
         int endIndex = -1;
         for (int p = 0; p < knuthParagraphs.size(); p++) {
+
+            KnuthSequence seq = knuthParagraphs.get(p);
+            LineLayoutPossibilities llPoss = lineLayoutsList[p];
             // penalty between paragraphs
             if (p > 0) {
                 Keep keep = getKeepTogether();
@@ -889,9 +892,6 @@
                             context));
             }
 
-            LineLayoutPossibilities llPoss = lineLayoutsList[p];
-            KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(p);
-
             if (!seq.isInlineSequence()) {
                 List<ListElement> targetList = new LinkedList<ListElement>();
                 ListIterator listIter = seq.listIterator();
@@ -918,10 +918,7 @@
                 for (int i = 0;
                         i < llPoss.getChosenLineCount();
                         i++) {
-                    if (returnList.size() > 0
-                            && i > 0 //if i==0 break generated above already
-                            && i >= fobj.getOrphans()
-                            && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
+                    if (returnList.size() > 0 && i > 0) {
                         // penalty allowing a page break between lines
                         Keep keep = getKeepTogether();
                         returnList.add(new BreakElement(
@@ -1149,7 +1146,7 @@
 
     /** {@inheritDoc} */
     public List getChangedKnuthElements(List oldList, int alignment) {
-        List returnList = new LinkedList();
+        List<KnuthElement> returnList = new LinkedList<KnuthElement>();
         for (int p = 0; p < knuthParagraphs.size(); p++) {
             LineLayoutPossibilities llPoss = lineLayoutsList[p];
             //log.debug("demerits of the chosen layout: " + llPoss.getChosenDemerits());
@@ -1392,7 +1389,7 @@
     public void addAreas(PositionIterator parentIter,
                          LayoutContext context) {
         while (parentIter.hasNext()) {
-            Position pos = (Position) parentIter.next();
+            Position pos = parentIter.next();
             boolean isLastPosition = !parentIter.hasNext();
             if (pos instanceof LineBreakPosition) {
                 addInlineArea(context, (LineBreakPosition) pos, isLastPosition);
@@ -1426,12 +1423,12 @@
                 (lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast),
                 lbp.difference, lbp.availableStretch, lbp.availableShrink);
         if (lbp.startIndent != 0) {
-            lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
+            lineArea.addTrait(Trait.START_INDENT, lbp.startIndent);
         }
         lineArea.setBPD(lbp.lineHeight);
         lineArea.setIPD(lbp.lineWidth);
-        lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
-        lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
+        lineArea.addTrait(Trait.SPACE_BEFORE, lbp.spaceBefore);
+        lineArea.addTrait(Trait.SPACE_AFTER, lbp.spaceAfter);
         alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
 
         if (seq instanceof Paragraph) {
