Fix for the two problems raised by Simon:
In some cases the element lists were processed in the wrong direction. Fixed by not reversing the list itself anymore but teaching the conditional handling to process the lists backwards.
The problem is now covered by block_space-before_space-after_9 and 9a.

While fixing this another problem surfaced with hard breaks where two element lists are generated.
The problem is now covered by block_space-before_space-after_9a.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_SpaceResolution@326900 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index 9c82728..743d305 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -76,8 +76,8 @@
             return this.startOn;
         }
 
-        public BlockSequence endBlockSequence() {
-            KnuthSequence temp = super.endSequence();
+        public BlockSequence endBlockSequence(Position breakPosition) {
+            KnuthSequence temp = super.endSequence(breakPosition);
             if (temp != null) {
                 BlockSequence returnSequence = new BlockSequence(startOn);
                 returnSequence.addAll(temp);
@@ -308,6 +308,10 @@
             
             int displayAlign = getCurrentDisplayAlign();
             
+            //The following is needed by SpaceResolver.performConditionalsNotification()
+            //further down as there may be important Position elements in the element list trailer
+            int notificationEndElementIndex = endElementIndex;
+
             // ignore the last elements added by the
             // PageSequenceLayoutManager
             endElementIndex -= (endElementIndex == (originalList.size() - 1)) 
@@ -329,12 +333,13 @@
             while (effectiveListIterator.hasNext()
                     && !(firstElement = (KnuthElement) effectiveListIterator.next())
                             .isBox()) {
+                /*
                 if (firstElement.isGlue() && firstElement.getLayoutManager() != null) {
                     // discard the space representd by the glue element
                     ((BlockLevelLayoutManager) firstElement
                             .getLayoutManager())
                             .discardSpace((KnuthGlue) firstElement);
-                }
+                }*/
                 startElementIndex++;
             }
 
@@ -380,7 +385,7 @@
 
                 // Handle SpaceHandling(Break)Positions, see SpaceResolver!
                 SpaceResolver.performConditionalsNotification(effectiveList, 
-                        startElementIndex, endElementIndex, lastBreak);
+                        startElementIndex, notificationEndElementIndex, lastBreak);
                 
                 // Add areas now!
                 addAreas(new KnuthPossPosIter(effectiveList,
@@ -439,10 +444,12 @@
             //Only implemented by the PSLM
             nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn);
             
+            Position breakPosition = null;
             if (((KnuthElement) returnedList.getLast()).isPenalty()
                     && ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
                 KnuthPenalty breakPenalty = (KnuthPenalty) returnedList
                         .removeLast();
+                breakPosition = breakPenalty.getPosition();
                 switch (breakPenalty.getBreakClass()) {
                 case Constants.EN_PAGE:
                     log.debug("PLM> break - PAGE");
@@ -468,7 +475,7 @@
             }
             blockList.addAll(returnedList);
             BlockSequence seq = null;
-            seq = blockList.endBlockSequence();
+            seq = blockList.endBlockSequence(breakPosition);
             if (seq != null) {
                 blockLists.add(seq);
             }
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index d8183bc..50281ef 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -229,12 +229,10 @@
             }
         }
 
-        if (!bSpaceBeforeServed) {
-            addKnuthElementsForSpaceBefore(returnList, alignment);
-            bSpaceBeforeServed = true;
-        }
+        addKnuthElementsForSpaceBefore(returnList, alignment);
         
-        addKnuthElementsForBorderPaddingBefore(returnList);
+        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+        firstVisibleMarkServed = true;
 
         if (autoHeight) {
             //Spaces, border and padding to be repeated at each break
@@ -256,6 +254,7 @@
                 if (returnedList.size() == 1
                         && ((KnuthElement)returnedList.getFirst()).isForcedBreak()) {
                     // a descendant of this block has break-before
+                    /*
                     if (returnList.size() == 0) {
                         // the first child (or its first child ...) has
                         // break-before;
@@ -263,7 +262,7 @@
                         // the
                         // following page
                         bSpaceBeforeServed = false;
-                    }
+                    }*/
                     contentList.addAll(returnedList);
 
                     // "wrap" the Position inside each element
@@ -352,7 +351,7 @@
                 }
             }
         }
-        addKnuthElementsForBorderPaddingAfter(returnList);
+        addKnuthElementsForBorderPaddingAfter(returnList, true);
         addKnuthElementsForSpaceAfter(returnList, alignment);
         addKnuthElementsForBreakAfter(returnList, context);
 
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index ac0abc2..b3ad722 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -55,8 +55,8 @@
     protected LinkedList storedList = null;
     /** Indicates whether break before has been served or not */
     protected boolean bBreakBeforeServed = false;
-    /** Indicates whether space before has been served or not */
-    protected boolean bSpaceBeforeServed = false;
+    /** Indicates whether the first visible mark has been returned by this LM, yet */
+    protected boolean firstVisibleMarkServed = false;
     /** Reference IPD available */
     protected int referenceIPD = 0;
     /**
@@ -218,12 +218,10 @@
             }
         }
 
-        if (!bSpaceBeforeServed) {
-            addKnuthElementsForSpaceBefore(returnList, alignment);
-            bSpaceBeforeServed = true;
-        }
+        addKnuthElementsForSpaceBefore(returnList, alignment);
         
-        addKnuthElementsForBorderPaddingBefore(returnList);
+        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+        firstVisibleMarkServed = true;
 
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
@@ -257,6 +255,7 @@
                     && returnedList.size() == 1
                     && ((ListElement) returnedList.getFirst()).isForcedBreak()) {
                 // a descendant of this block has break-before
+                /*
                 if (returnList.size() == 0) {
                     // the first child (or its first child ...) has
                     // break-before;
@@ -264,7 +263,7 @@
                     // the
                     // following page
                     bSpaceBeforeServed = false;
-                }
+                }*/
                 contentList.addAll(returnedList);
 
                 /* extension: conversione di tutta la sequenza fin'ora ottenuta */
@@ -369,7 +368,7 @@
             returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
         }
 
-        addKnuthElementsForBorderPaddingAfter(returnList);
+        addKnuthElementsForBorderPaddingAfter(returnList, true);
         addKnuthElementsForSpaceAfter(returnList, alignment);
         addKnuthElementsForBreakAfter(returnList, context);
 
@@ -858,7 +857,7 @@
      * Creates Knuth elements for before border padding and adds them to the return list.
      * @param returnList return list to add the additional elements to
      */
-    protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList) {
+    protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList, boolean isFirst) {
         //Border and Padding (before)
         CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
         if (borderAndPadding != null) {
@@ -866,14 +865,15 @@
                 returnList.add(new BorderElement(
                         getAuxiliaryPosition(), 
                         borderAndPadding.getBorderInfo(CommonBorderPaddingBackground.BEFORE)
-                            .getWidth(), RelSide.BEFORE, true, false, this));
+                                .getWidth(),
+                        RelSide.BEFORE, isFirst, false, this));
             }
             if (borderAndPadding.getPaddingBefore(false, this) > 0) {
                 returnList.add(new PaddingElement(
                         getAuxiliaryPosition(),
                         borderAndPadding.getPaddingLengthProperty(
                                 CommonBorderPaddingBackground.BEFORE), 
-                                RelSide.BEFORE, true, false, this));
+                        RelSide.BEFORE, isFirst, false, this));
             }
             //TODO Handle conditionality
             /*
@@ -889,7 +889,7 @@
      * Creates Knuth elements for after border padding and adds them to the return list.
      * @param returnList return list to add the additional elements to
      */
-    protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList) {
+    protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList, boolean isLast) {
         //Border and Padding (after)
         CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
         if (borderAndPadding != null) {
@@ -897,13 +897,15 @@
                 returnList.add(new PaddingElement(
                         getAuxiliaryPosition(),
                         borderAndPadding.getPaddingLengthProperty(
-                                CommonBorderPaddingBackground.AFTER), RelSide.AFTER, false, true, this));
+                                CommonBorderPaddingBackground.AFTER),
+                        RelSide.AFTER, false, isLast, this));
             }
             if (borderAndPadding.getBorderAfterWidth(false) > 0) {
                 returnList.add(new BorderElement(
                         getAuxiliaryPosition(), 
                         borderAndPadding.getBorderInfo(CommonBorderPaddingBackground.AFTER)
-                            .getWidth(), RelSide.AFTER, false, true, this));
+                                .getWidth(),
+                        RelSide.AFTER, false, isLast, this));
             }
             //TODO Handle conditionality
             /*
diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 62f5e2a..3ec814b 100644
--- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -132,7 +132,7 @@
                 }
                 if (returnedList.size() > 0) {
                     returnList.addAll(returnedList);
-                    if (ElementListUtils.endsWithForcedBreak(returnedList)) {
+                    if (ElementListUtils.endsWithForcedBreak(returnList)) {
                         // a descendant of this flow has break-after
                         SpaceResolver.resolveElementList(returnList);
                         return returnList;
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
index 77f30f1..15a61a1 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
@@ -53,9 +53,19 @@
     }
 
     /**
+     * Finalizes a Knuth sequence.
      * @return a finalized sequence.
      */
     public KnuthSequence endSequence() {
+        return endSequence(null);
+    }
+    
+    /**
+     * Finalizes a Knuth sequence.
+     * @param breakPosition a Position instance for the last penalty (may be null)
+     * @return a finalized sequence.
+     */
+    public KnuthSequence endSequence(Position breakPosition) {
         // remove glue and penalty item at the end of the paragraph
         while (this.size() > ignoreAtStart
                && !((KnuthElement)this.get(this.size() - 1)).isBox()) {
@@ -66,7 +76,7 @@
             // and the forced break
             this.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false));
             this.add(new KnuthGlue(0, 10000000, 0, null, false));
-            this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));
+            this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, breakPosition, false));
             ignoreAtEnd = 3;
             return this;
         } else {
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
index 49e4161..45e9990 100644
--- a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
+++ b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
@@ -18,6 +18,7 @@
 
 package org.apache.fop.layoutmgr;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -74,9 +75,9 @@
         int i = 0;
         ListIterator iter;
         if (first != null) {
-            iter = first.listIterator(first.size());
-            while (iter.hasPrevious()) {
-                noBreak[i] = (UnresolvedListElementWithLength)iter.previous();
+            iter = first.listIterator();
+            while (iter.hasNext()) {
+                noBreak[i] = (UnresolvedListElementWithLength)iter.next();
                 noBreakLengths[i] = noBreak[i].getLength();
                 i++;
             }
@@ -152,15 +153,21 @@
     }
     
     private void removeConditionalBorderAndPadding(
-                UnresolvedListElement[] elems, MinOptMax[] lengths) {
+                UnresolvedListElement[] elems, MinOptMax[] lengths, boolean reverse) {
         for (int i = 0; i < elems.length; i++) {
-            if (elems[i] instanceof BorderOrPaddingElement) {
-                BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[i];
+            int effIndex;
+            if (reverse) {
+                effIndex = elems.length - 1 - i;
+            } else {
+                effIndex = i;
+            }
+            if (elems[effIndex] instanceof BorderOrPaddingElement) {
+                BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[effIndex];
                 if (bop.isConditional() && !(bop.isFirst() || bop.isLast())) {
                     if (log.isDebugEnabled()) {
                         log.debug("Nulling conditional element: " + bop);
                     }
-                    lengths[i] = null;
+                    lengths[effIndex] = null;
                 }
             }
         }
@@ -169,21 +176,28 @@
         }
     }
     
-    private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths) {
+    private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths,
+                    boolean reverse) {
         for (int i = 0; i < elems.length; i++) {
-            if (lengths[i] == null) {
+            int effIndex;
+            if (reverse) {
+                effIndex = elems.length - 1 - i;
+            } else {
+                effIndex = i;
+            }
+            if (lengths[effIndex] == null) {
                 //Zeroed border or padding doesn't create a fence
                 continue;
-            } else if (elems[i] instanceof BorderOrPaddingElement) {
+            } else if (elems[effIndex] instanceof BorderOrPaddingElement) {
                 //Border or padding form fences!
                 break;
-            } else if (!elems[i].isConditional()) {
+            } else if (!elems[effIndex].isConditional()) {
                 break;
             }
             if (log.isDebugEnabled()) {
-                log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[i]);
+                log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[effIndex]);
             }
-            lengths[i] = null;
+            lengths[effIndex] = null;
         }
         if (log.isTraceEnabled() && elems.length > 0) {
             log.trace("-->Resulting list: " + toString(elems, lengths));
@@ -341,24 +355,55 @@
         }
     }
     
+    private boolean hasFirstPart() {
+        return firstPart != null && firstPart.length > 0;
+    }
+    
+    private boolean hasSecondPart() {
+        return secondPart != null && secondPart.length > 0;
+    }
+    
     private void resolve() {
         if (breakPoss != null) {
-            if (firstPart != null) {
-                removeConditionalBorderAndPadding(firstPart, firstPartLengths);
-                performSpaceResolutionRule1(firstPart, firstPartLengths);
+            if (hasFirstPart()) {
+                removeConditionalBorderAndPadding(firstPart, firstPartLengths, true);
+                performSpaceResolutionRule1(firstPart, firstPartLengths, true);
                 performSpaceResolutionRules2to3(firstPart, firstPartLengths);
             }
-            if (secondPart != null) {
-                removeConditionalBorderAndPadding(secondPart, secondPartLengths);
-                performSpaceResolutionRule1(secondPart, secondPartLengths);
+            if (hasSecondPart()) {
+                removeConditionalBorderAndPadding(secondPart, secondPartLengths, false);
+                performSpaceResolutionRule1(secondPart, secondPartLengths, false);
                 performSpaceResolutionRules2to3(secondPart, secondPartLengths);
             }
             if (noBreak != null) {
                 performSpaceResolutionRules2to3(noBreak, noBreakLengths);
             }
         } else {
-            if (isFirst || isLast) {
-                performSpaceResolutionRule1(secondPart, secondPartLengths);
+            if (isFirst) {
+                removeConditionalBorderAndPadding(secondPart, secondPartLengths, false);
+                performSpaceResolutionRule1(secondPart, secondPartLengths, false);
+            }
+            if (isLast) {
+                removeConditionalBorderAndPadding(firstPart, firstPartLengths, true);
+                performSpaceResolutionRule1(firstPart, firstPartLengths, true);
+            }
+            
+            if (hasFirstPart()) {
+                //Now that we've handled isFirst/isLast conditions, we need to look at the
+                //active part in its normal order so swap it back.
+                log.trace("Swapping first and second parts.");
+                UnresolvedListElementWithLength[] tempList;
+                MinOptMax[] tempLengths;
+                tempList = secondPart;
+                tempLengths = secondPartLengths;
+                secondPart = firstPart;
+                secondPartLengths = firstPartLengths;
+                firstPart = tempList;
+                firstPartLengths = tempLengths;
+                if (hasFirstPart()) {
+                    throw new IllegalStateException("Didn't expect more than one parts in a"
+                            + "no-break condition.");
+                }
             }
             performSpaceResolutionRules2to3(secondPart, secondPartLengths);
         }
@@ -396,7 +441,7 @@
         glue2shrink -= glue1.opt - glue1.min;
         glue2shrink -= glue3.opt - glue3.min;
         
-        
+        boolean hasPrecedingNonBlock = false;
         if (log.isDebugEnabled()) {
             log.debug("noBreakLength=" + noBreakLength 
                     + ", glue1=" + glue1 
@@ -439,8 +484,9 @@
                     false, (Position)null, true));
             iter.add(new KnuthGlue(glue3.opt, glue3.max - glue3.opt, glue3.opt - glue3.min, 
                     (Position)null, true));
+            hasPrecedingNonBlock = true;
         }
-        if (isLast) {
+        if (isLast && hasPrecedingNonBlock) {
             //Otherwise, the preceding penalty and glue will be cut off
             iter.add(new KnuthBox(0, (Position)null, true));
         }
@@ -494,9 +540,7 @@
                 }
             } else {
                 for (int i = 0; i < resolver.noBreak.length; i++) {
-                    if (resolver.noBreak[i] instanceof SpaceElement) {
-                        resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]);
-                    }
+                    resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]);
                 }
             }
         }
@@ -550,9 +594,7 @@
                 throw new IllegalStateException("Only applicable to no-break situations");
             }
             for (int i = 0; i < resolver.secondPart.length; i++) {
-                if (resolver.secondPart[i] instanceof SpaceElement) {
-                    resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]);
-                }
+                resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]);
             }
         }
         
@@ -619,18 +661,14 @@
                     }
                 }
                 //last = !iter.hasNext();
-                if (breakPoss == null & unresolvedSecond.size() == 0) {
+                if (breakPoss == null && unresolvedSecond.size() == 0 && !last) {
+                    log.trace("Swap first and second parts in no-break condition,"
+                            + " second part is empty.");
                     //The first list is reversed, so swap if this shouldn't happen
                     List swapList = unresolvedSecond;
                     unresolvedSecond = unresolvedFirst;
                     unresolvedFirst = swapList;
                 }
-                //Need to reverse the order of the first part
-                //From here on further down, the first part in the unresolved list is 
-                //always the one nearest to the break.
-                if (unresolvedFirst.size() > 0) {
-                    Collections.reverse(unresolvedFirst);
-                }
                 
                 log.debug("----start space resolution (first=" + first + ", last=" + last + ")...");
                 SpaceResolver resolver = new SpaceResolver(
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index e7478fe..c8cedb0 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -184,10 +184,7 @@
         
         LinkedList returnList = new LinkedList();
         
-        if (!bSpaceBeforeServed) {
-            addKnuthElementsForSpaceBefore(returnList, alignment);
-            bSpaceBeforeServed = true;
-        }
+        addKnuthElementsForSpaceBefore(returnList, alignment);
         
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 4d55174..f805fe9 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -181,7 +181,8 @@
         addKnuthElementsForSpaceBefore(returnList, alignment);
         
         if (getTable().isSeparateBorderModel()) {
-            addKnuthElementsForBorderPaddingBefore(returnList);
+            addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+            firstVisibleMarkServed = true;
         }
 
         //Spaces, border and padding to be repeated at each break
@@ -283,7 +284,7 @@
         }
         wrapPositionElements(contentList, returnList);
         if (getTable().isSeparateBorderModel()) {
-            addKnuthElementsForBorderPaddingAfter(returnList);
+            addKnuthElementsForBorderPaddingAfter(returnList, true);
         }
         addKnuthElementsForSpaceAfter(returnList, alignment);
         addKnuthElementsForBreakAfter(returnList, context);
diff --git a/test/layoutengine/testcases/block-container_space-before_space-after_1.xml b/test/layoutengine/testcases/block-container_space-before_space-after_1.xml
index ed4615b..37b7b87 100644
--- a/test/layoutengine/testcases/block-container_space-before_space-after_1.xml
+++ b/test/layoutengine/testcases/block-container_space-before_space-after_1.xml
@@ -154,8 +154,6 @@
       
       <box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
       
-      <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-      
       <skip>3</skip>
     </element-list>
   </checks>
diff --git a/test/layoutengine/testcases/block_space-before_space-after_2.xml b/test/layoutengine/testcases/block_space-before_space-after_2.xml
index 14944f2..0676277 100644
--- a/test/layoutengine/testcases/block_space-before_space-after_2.xml
+++ b/test/layoutengine/testcases/block_space-before_space-after_2.xml
@@ -150,8 +150,6 @@
       
       <box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
       
-      <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-      
       <skip>3</skip>
     </element-list>
   </checks>
diff --git a/test/layoutengine/testcases/block_space-before_space-after_9.xml b/test/layoutengine/testcases/block_space-before_space-after_9.xml
new file mode 100644
index 0000000..4df4591
--- /dev/null
+++ b/test/layoutengine/testcases/block_space-before_space-after_9.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks if the isLast case is properly handled. In this case the part list has to be 
+      reversed to do the conditionals removal, but then has to be reversed again to its natural order 
+      so space resolution rules 2 and 3 are properly performed.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="1in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block space-before="11pt" space-after="11pt">
+            <fo:block space-before="12pt" space-after="12pt">
+              <fo:block space-before="13pt" space-after="13pt" border="solid 1pt">
+                Apache FOP!
+              </fo:block>
+            </fo:block>
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <element-list category="breaker">
+      <box w="0"/>
+      <penalty w="0" p="INF"/>
+      <glue w="1000"/>
+      
+      <box w="14400"/>
+      
+      <box w="0"/>
+      <penalty w="0" p="INF"/>
+      <glue w="1000"/>
+      
+      <box w="0"/>
+      <skip>3</skip>
+    </element-list>
+    <true xpath="not(boolean(//flow/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//flow/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//flow/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//flow/block[1]/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//flow/block[1]/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//flow/block[1]/block[1]/block[1]/@space-after))"/>
+    <eval expected="1000 1000 1000 1000" xpath="//flow/block[1]/block[1]/block[1]/@bap"/>
+  </checks>
+</testcase>
diff --git a/test/layoutengine/testcases/block_space-before_space-after_9a.xml b/test/layoutengine/testcases/block_space-before_space-after_9a.xml
new file mode 100644
index 0000000..07f3783
--- /dev/null
+++ b/test/layoutengine/testcases/block_space-before_space-after_9a.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks if the isLast case is properly handled. In this case the part list has to be 
+      reversed to do the conditionals removal, but then has to be reversed again to its natural order 
+      so space resolution rules 2 and 3 are properly performed.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="1in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block space-before="11pt" space-after="11pt">
+            <fo:block space-before="12pt" space-after="12pt">
+              <fo:block space-before="13pt" space-after="13pt" border="solid 1pt">
+                Apache FOP!
+                <fo:block break-before="page"/>
+                Apache FOP!!!
+              </fo:block>
+            </fo:block>
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <element-list category="breaker" index="0">
+      <box w="0"/> <!-- SpaceHandlingPosition -->
+      <penalty w="0" p="INF"/>
+      <glue w="1000"/>
+      
+      <box w="14400"/>
+      
+      <skip>3</skip> <!-- the last of the three holds a SpaceHandlingBreakPosition -->
+    </element-list>
+    <element-list category="breaker" index="1">
+      <box w="0"/> <!-- SpaceHandlingPosition -->
+      
+      <box w="0"/> <!-- empty block used to cause the break-before -->
+      <penalty w="0" p="0"/>
+      
+      <box w="14400"/>
+      
+      <box w="0"/>
+      <penalty w="0" p="INF"/>
+      <glue w="1000"/>
+      <box w="0"/> <!-- SpaceHandlingPosition -->
+
+      <skip>3</skip>
+    </element-list>
+    
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-after))"/>
+    <eval expected="1000 1000 1000 0" xpath="//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@bap"/>
+
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-after))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-before))"/>
+    <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-after))"/>
+    <eval expected="1000 1000 0 1000" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@bap"/>
+  </checks>
+</testcase>
diff --git a/test/layoutengine/testcases/list-block_space-before_space-after_1.xml b/test/layoutengine/testcases/list-block_space-before_space-after_1.xml
index 4c77cc0..82af9d2 100644
--- a/test/layoutengine/testcases/list-block_space-before_space-after_1.xml
+++ b/test/layoutengine/testcases/list-block_space-before_space-after_1.xml
@@ -196,8 +196,6 @@
       
       <box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
       
-      <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-      
       <skip>3</skip>
     </element-list>
 
diff --git a/test/layoutengine/testcases/region_side_space-resolution.xml b/test/layoutengine/testcases/region_side_space-resolution.xml
index a7e8af0..912fa6e 100644
--- a/test/layoutengine/testcases/region_side_space-resolution.xml
+++ b/test/layoutengine/testcases/region_side_space-resolution.xml
@@ -52,7 +52,6 @@
       <box w="14400"/>
       
       <box w="0"/> <!-- SpaceHandlingPosition -->
-      <box w="0"/>
       <skip>3</skip>
     </element-list>
 
diff --git a/test/layoutengine/testcases/table_space-before_space-after_1.xml b/test/layoutengine/testcases/table_space-before_space-after_1.xml
index 2d30410..430d868 100644
--- a/test/layoutengine/testcases/table_space-before_space-after_1.xml
+++ b/test/layoutengine/testcases/table_space-before_space-after_1.xml
@@ -178,8 +178,6 @@
       
       <box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
       
-      <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-      
       <skip>3</skip>
     </element-list>