/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.layoutmgr;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

import org.apache.fop.area.Area;
import org.apache.fop.area.BlockParent;
import org.apache.fop.area.Block;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.layoutmgr.inline.LineLayoutManager;
import org.apache.fop.traits.MinOptMax;

/**
 * Base LayoutManager class for all areas which stack their child
 * areas in the block-progression direction, such as Flow, Block, ListBlock.
 */
public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                                                 implements BlockLevelLayoutManager {
    /**
     * Reference to FO whose areas it's managing or to the traits
     * of the FO.
     */
    //protected LayoutManager curChildLM = null; AbstractLayoutManager also defines this!
    protected BlockParent parentArea = null;

    /** Value of the block-progression-unit (non-standard property) */
    protected int bpUnit = 0;
    /** space-before value adjusted for block-progression-unit handling */
    protected int adjustedSpaceBefore = 0;
    /** space-after value adjusted for block-progression-unit handling */
    protected int adjustedSpaceAfter = 0;
    /** Only used to store the original list when createUnitElements is called */
    protected LinkedList storedList = null;
    /** Indicates whether break before has been served or not */
    protected boolean breakBeforeServed = 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;
    /** the effective start-indent value */
    protected int startIndent = 0;
    /** the effective end-indent value */
    protected int endIndent = 0;
    /**
     * Holds the (one-time use) fo:block space-before
     * and -after properties.  Large fo:blocks are split
     * into multiple Area. Blocks to accomodate the subsequent
     * regions (pages) they are placed on.  space-before
     * is applied at the beginning of the first
     * Block and space-after at the end of the last Block
     * used in rendering the fo:block.
     */
    protected MinOptMax foSpaceBefore = null;
    /** see foSpaceBefore */
    protected MinOptMax foSpaceAfter = null;

    private Position auxiliaryPosition;

    private int contentAreaIPD = 0;
    
    /**
     * @param node the fo this LM deals with
     */
    public BlockStackingLayoutManager(FObj node) {
        super(node);
        setGeneratesBlockArea(true);
    }

    /** 
     * @return current area being filled
     */
    protected BlockParent getCurrentArea() {
        return this.parentArea;
    }


    /**
     * Set the current area being filled.
     * @param parentArea the current area to be filled
     */
    protected void setCurrentArea(BlockParent parentArea) {
        this.parentArea = parentArea;
    }

    /**
     * Add a block spacer for space before and space after a block.
     * This adds an empty Block area that acts as a block space.
     *
     * @param adjust the adjustment value
     * @param minoptmax the min/opt/max value of the spacing
     */
    public void addBlockSpacing(double adjust, MinOptMax minoptmax) {
        int sp = TraitSetter.getEffectiveSpace(adjust, minoptmax);
        if (sp != 0) {
            Block spacer = new Block();
            spacer.setBPD(sp);
            parentLM.addChildArea(spacer);
        }
    }

    /**
     * Add the childArea to the passed area.
     * Called by child LayoutManager when it has filled one of its areas.
     * The LM should already have an Area in which to put the child.
     * See if the area will fit in the current area.
     * If so, add it. Otherwise initiate breaking.
     * @param childArea the area to add: will be some block-stacked Area.
     * @param parentArea the area in which to add the childArea
     */
    protected void addChildToArea(Area childArea,
                                     BlockParent parentArea) {
        // This should be a block-level Area (Block in the generic sense)
        if (!(childArea instanceof Block)) {
            //log.error("Child not a Block in BlockStackingLM!");
        }

        parentArea.addBlock((Block) childArea);
        flush(); // hand off current area to parent
    }


    /**
     * Add the childArea to the current area.
     * Called by child LayoutManager when it has filled one of its areas.
     * The LM should already have an Area in which to put the child.
     * See if the area will fit in the current area.
     * If so, add it. Otherwise initiate breaking.
     * @param childArea the area to add: will be some block-stacked Area.
     */
    public void addChildArea(Area childArea) {
        addChildToArea(childArea, getCurrentArea());
    }

    /**
     * Force current area to be added to parent area.
     */
    protected void flush() {
        if (getCurrentArea() != null) {
            parentLM.addChildArea(getCurrentArea());
        }
    }

    /** @return a cached auxiliary Position instance used for things like spaces. */
    protected Position getAuxiliaryPosition() {
        if (this.auxiliaryPosition == null) {
            this.auxiliaryPosition = new NonLeafPosition(this, null);
        }
        return this.auxiliaryPosition;
    }
    
    /**
     * @param len length in millipoints to span with bp units
     * @return the minimum integer n such that n * bpUnit >= len
     */
    protected int neededUnits(int len) {
        return (int) Math.ceil((float)len / bpUnit);
    }

    /**
     * Determines and sets the content area IPD based on available reference area IPD, start- and
     * end-indent properties.
     * end-indent is adjusted based on overconstrained geometry rules, if necessary.
     * @return the resulting content area IPD
     */
    protected int updateContentAreaIPDwithOverconstrainedAdjust() {
        int ipd = referenceIPD - (startIndent + endIndent);
        if (ipd < 0) {
            //5.3.4, XSL 1.0, Overconstrained Geometry
            log.debug("Adjusting end-indent based on overconstrained geometry rules for " + fobj);
            endIndent += ipd;
            ipd = 0;
            //TODO Should we skip layout for a block that has ipd=0?
        }
        setContentAreaIPD(ipd);
        return ipd;
    }
    
    /**
     * Sets the content area IPD by directly supplying the value. 
     * end-indent is adjusted based on overconstrained geometry rules, if necessary.
     * @return the resulting content area IPD
     */
    protected int updateContentAreaIPDwithOverconstrainedAdjust(int contentIPD) {
        int ipd = referenceIPD - (contentIPD + (startIndent + endIndent));
        if (ipd < 0) {
            //5.3.4, XSL 1.0, Overconstrained Geometry
            log.debug("Adjusting end-indent based on overconstrained geometry rules for " + fobj);
            endIndent += ipd;
        }
        setContentAreaIPD(contentIPD);
        return contentIPD;
    }
    
    /**
     * @see LayoutManager#getNextKnuthElements(LayoutContext, int)
     */
    public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
        //log.debug("BLM.getNextKnuthElements> keep-together = "
              // + layoutProps.keepTogether.getType());
        //log.debug(" keep-with-previous = " +
              // layoutProps.keepWithPrevious.getType());
        //log.debug(" keep-with-next = " +
              // layoutProps.keepWithNext.getType());
        BlockLevelLayoutManager curLM; // currently active LM
        BlockLevelLayoutManager prevLM = null; // previously active LM

        referenceIPD = context.getRefIPD();
        
        updateContentAreaIPDwithOverconstrainedAdjust();

        LinkedList returnedList = null;
        LinkedList contentList = new LinkedList();
        LinkedList returnList = new LinkedList();

        if (!breakBeforeServed) {
            try {
                if (addKnuthElementsForBreakBefore(returnList, context)) {
                    return returnList;
                }
            } finally {
                breakBeforeServed = true;
            }
        }

        if (!firstVisibleMarkServed) {
            addKnuthElementsForSpaceBefore(returnList, alignment);
        }
        
        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
        firstVisibleMarkServed = true;

        //Spaces, border and padding to be repeated at each break
        addPendingMarks(context);
        
        while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
            LayoutContext childLC = new LayoutContext(0);
            childLC.copyPendingMarksFrom(context);
            if (curLM instanceof LineLayoutManager) {
                // curLM is a LineLayoutManager
                // set stackLimit for lines (stack limit is now i-p-direction, not b-p-direction!)
                childLC.setStackLimit(new MinOptMax(getContentAreaIPD()));
                childLC.setRefIPD(getContentAreaIPD());
            } else {
                // curLM is a ?
                //childLC.setStackLimit(MinOptMax.subtract(context
                //        .getStackLimit(), stackSize));
                childLC.setStackLimit(context.getStackLimit());
                childLC.setRefIPD(referenceIPD);
            }

            // get elements from curLM
            returnedList = curLM.getNextKnuthElements(childLC, alignment);
            if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
                context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
                childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
            }
            if (returnedList != null
                    && 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;
                    // all this block, including space before, will be put in
                    // the
                    // following page
                    bSpaceBeforeServed = false;
                }*/
                contentList.addAll(returnedList);

                /* extension: conversione di tutta la sequenza fin'ora ottenuta */
                if (bpUnit > 0) {
                    storedList = contentList;
                    contentList = createUnitElements(contentList);
                }
                /* end of extension */

                // "wrap" the Position inside each element
                // moving the elements from contentList to returnList
                returnedList = new LinkedList();
                wrapPositionElements(contentList, returnList);

                return returnList;
            } else {
                if (prevLM != null) {
                    // there is a block handled by prevLM
                    // before the one handled by curLM
                    if (mustKeepTogether() 
                            || context.isKeepWithNextPending()
                            || childLC.isKeepWithPreviousPending()) {
                        // Clear keep pending flag
                        context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
                        // add an infinite penalty to forbid a break between
                        // blocks
                        contentList.add(new BreakElement(
                                new Position(this), KnuthElement.INFINITE, context));
                    } else if (!((ListElement) contentList.getLast()).isGlue()) {
                        // add a null penalty to allow a break between blocks
                        contentList.add(new BreakElement(
                                new Position(this), 0, context));
                    } else {
                        // the last element in contentList is a glue;
                        // it is a feasible breakpoint, there is no need to add
                        // a penalty
                        log.warn("glue-type break possibility not handled properly, yet");
                        //TODO Does this happen? If yes, need to deal with border and padding
                        //at the break possibility
                    }
                }
                if (returnedList == null || returnedList.size() == 0) {
                    //Avoid NoSuchElementException below (happens with empty blocks)
                    continue;
                }
                contentList.addAll(returnedList);
                if (((ListElement) returnedList.getLast()).isForcedBreak()) {
                    // a descendant of this block has break-after

                    /* extension: conversione di tutta la sequenza fin'ora ottenuta */
                    if (bpUnit > 0) {
                        storedList = contentList;
                        contentList = createUnitElements(contentList);
                    }
                    /* end of extension */

                    returnedList = new LinkedList();
                    wrapPositionElements(contentList, returnList);

                    return returnList;
                }
            }
            // propagate and clear
            context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, childLC.isKeepWithNextPending());
            childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
            childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
            prevLM = curLM;
        }

        /* Extension: conversione di tutta la sequenza fin'ora ottenuta */
        if (bpUnit > 0) {
            storedList = contentList;
            contentList = createUnitElements(contentList);
        }
        /* end of extension */

        returnedList = new LinkedList();
        if (contentList.size() > 0) {
            wrapPositionElements(contentList, returnList);
        } else {
            //Empty fo:block, zero-length box makes sure the IDs are registered.
            returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
        }

        addKnuthElementsForBorderPaddingAfter(returnList, true);
        addKnuthElementsForSpaceAfter(returnList, alignment);
        addKnuthElementsForBreakAfter(returnList, context);

        if (mustKeepWithNext()) {
            context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
        }
        if (mustKeepWithPrevious()) {
            context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
        }
        
        setFinished(true);

        return returnList;
    }

    /**
     * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
     */
    public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
/*LF*/  //log.debug("  BLM.negotiateBPDAdjustment> " + adj);
/*LF*/  //log.debug("  lastElement e' " + (lastElement.isPenalty() 
        //      ? "penalty" : (lastElement.isGlue() ? "glue" : "box" )));
/*LF*/  //log.debug("  position e' " + lastElement.getPosition().getClass().getName());
/*LF*/  //log.debug("  " + (bpUnit > 0 ? "unit" : ""));
        Position innerPosition = ((NonLeafPosition) lastElement.getPosition()).getPosition();

        if (innerPosition == null && lastElement.isGlue()) {
            // this adjustment applies to space-before or space-after of this block
            if (((KnuthGlue) lastElement).getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
                // this adjustment applies to space-before
                adjustedSpaceBefore += adj;
/*LF*/          //log.debug("  BLM.negotiateBPDAdjustment> spazio prima: " + adj);
            } else {
                // this adjustment applies to space-after
                adjustedSpaceAfter += adj;
/*LF*/          //log.debug("  BLM.negotiateBPDAdjustment> spazio dopo: " + adj);
            }
            return adj;
        } else if (innerPosition instanceof MappingPosition) {
            // this block has block-progression-unit > 0: the adjustment can concern
            // - the space-before or space-after of this block, 
            // - the line number of a descendant of this block
            MappingPosition mappingPos = (MappingPosition)innerPosition; 
            if (lastElement.isGlue()) {
                // lastElement is a glue
/*LF*/          //log.debug("  BLM.negotiateBPDAdjustment> bpunit con glue");
                ListIterator storedListIterator = storedList.listIterator(
                        mappingPos.getFirstIndex());
                int newAdjustment = 0;
                while (storedListIterator.nextIndex() <= mappingPos.getLastIndex()) {
                    KnuthElement storedElement = (KnuthElement)storedListIterator.next();
                    if (storedElement.isGlue()) {
                        newAdjustment += ((BlockLevelLayoutManager)storedElement
                                .getLayoutManager()).negotiateBPDAdjustment(
                                        adj - newAdjustment, storedElement);
/*LF*/                  //log.debug("  BLM.negotiateBPDAdjustment> (progressivo) righe: " 
                        //  + newAdjustment);
                    }
                }
                newAdjustment = (newAdjustment > 0 ? bpUnit * neededUnits(newAdjustment)
                                                   : -bpUnit * neededUnits(-newAdjustment));
                return newAdjustment;
            } else {
                // lastElement is a penalty: this means that the paragraph
                // has been split between consecutive pages:
                // this may involve a change in the number of lines
/*LF*/          //log.debug("  BLM.negotiateBPDAdjustment> bpunit con penalty");
                KnuthPenalty storedPenalty = (KnuthPenalty)
                                             storedList.get(mappingPos.getLastIndex());
                if (storedPenalty.getW() > 0) {
                    // the original penalty has width > 0
/*LF*/              //log.debug("  BLM.negotiateBPDAdjustment> chiamata passata");
                    return ((BlockLevelLayoutManager)storedPenalty.getLayoutManager())
                           .negotiateBPDAdjustment(storedPenalty.getW(), 
                                   (KnuthElement)storedPenalty);
                } else {
                    // the original penalty has width = 0
                    // the adjustment involves only the spaces before and after
/*LF*/              //log.debug("  BLM.negotiateBPDAdjustment> chiamata gestita");
                    return adj;
                }
            }
        } else if (innerPosition.getLM() != this) {
            // this adjustment concerns another LM
            NonLeafPosition savedPos = (NonLeafPosition) lastElement.getPosition();
            lastElement.setPosition(innerPosition);
            int returnValue = ((BlockLevelLayoutManager)lastElement.getLayoutManager())
                    .negotiateBPDAdjustment(adj, lastElement);
            lastElement.setPosition(savedPos);
/*LF*/      //log.debug("  BLM.negotiateBPDAdjustment> righe: " + returnValue);
            return returnValue;
        } else {
            // this should never happen
            log.error("BlockLayoutManager.negotiateBPDAdjustment(): unexpected Position");
            return 0;
        }
    }

    /**
     * @see BlockLevelLayoutManager#discardSpace(KnuthGlue)
     */
    public void discardSpace(KnuthGlue spaceGlue) {
        //log.debug("  BLM.discardSpace> " + spaceGlue.getPosition().getClass().getName());
        Position innerPosition = ((NonLeafPosition) spaceGlue.getPosition()).getPosition();

        if (innerPosition == null || innerPosition.getLM() == this) {
            // if this block has block-progression-unit > 0, innerPosition can be
            // a MappingPosition
            // spaceGlue represents space before or space after of this block
            if (spaceGlue.getAdjustmentClass() == SPACE_BEFORE_ADJUSTMENT) {
                // space-before must be discarded
                adjustedSpaceBefore = 0;
                foSpaceBefore = new MinOptMax(0);
            } else {
                // space-after must be discarded
                adjustedSpaceAfter = 0;
                foSpaceAfter = new MinOptMax(0);
                //TODO Why are both cases handled in the same way?
            }
        } else {
            // this element was not created by this BlockLM
            NonLeafPosition savedPos = (NonLeafPosition)spaceGlue.getPosition();
            spaceGlue.setPosition(innerPosition);
            ((BlockLevelLayoutManager) spaceGlue.getLayoutManager()).discardSpace(spaceGlue);
            spaceGlue.setPosition(savedPos);
        }
    }

    /**
     * @see LayoutManager#getChangedKnuthElements(List, int)
     */
    public LinkedList getChangedKnuthElements(List oldList, int alignment) {
/*LF*/  //log.debug("");
/*LF*/  //log.debug("  BLM.getChangedKnuthElements> inizio: oldList.size() = " 
        //  + oldList.size());
        ListIterator oldListIterator = oldList.listIterator();
        KnuthElement returnedElement;
        KnuthElement currElement = null;
        KnuthElement prevElement = null;
        LinkedList returnedList = new LinkedList();
        LinkedList returnList = new LinkedList();
        int fromIndex = 0;

        // "unwrap" the Positions stored in the elements
        KnuthElement oldElement = null;
        while (oldListIterator.hasNext()) {
            oldElement = (KnuthElement)oldListIterator.next();
            Position innerPosition = ((NonLeafPosition) oldElement.getPosition()).getPosition();
            //log.debug(" BLM> unwrapping: " 
            //  + (oldElement.isBox() ? "box    " : (oldElement.isGlue() ? "glue   " : "penalty")) 
            //  + " creato da " + oldElement.getLayoutManager().getClass().getName());
            //log.debug(" BLM> unwrapping:         " 
            //  + oldElement.getPosition().getClass().getName());
            if (innerPosition != null) {
                // oldElement was created by a descendant of this BlockLM
                oldElement.setPosition(innerPosition);
            } else {
                // thisElement was created by this BlockLM
                // modify its position in order to recognize it was not created
                // by a child
                oldElement.setPosition(new Position(this));
            }
        }

        // create the iterator
        List workList;
        if (bpUnit == 0) {
            workList = oldList;
        } else {
            // the storedList must be used instead of oldList;
            // find the index of the first element of returnedList
            // corresponding to the first element of oldList
            oldListIterator = oldList.listIterator();
            KnuthElement el = (KnuthElement) oldListIterator.next();
            while (!(el.getPosition() instanceof MappingPosition)) {
                el = (KnuthElement) oldListIterator.next();
            }
            int iFirst = ((MappingPosition) el.getPosition()).getFirstIndex();

            // find the index of the last element of returnedList
            // corresponding to the last element of oldList
            oldListIterator = oldList.listIterator(oldList.size());
            el = (KnuthElement) oldListIterator.previous();
            while (!(el.getPosition() instanceof MappingPosition)) {
                el = (KnuthElement) oldListIterator.previous();
            }
            int iLast = ((MappingPosition) el.getPosition()).getLastIndex();

            //log-debug("  si usa storedList da " + iFirst + " a " + iLast 
            //  + " compresi su " + storedList.size() + " elementi totali");
            workList = storedList.subList(iFirst, iLast + 1);
        }
        ListIterator workListIterator = workList.listIterator();

        //log.debug("  BLM.getChangedKnuthElements> workList.size() = " 
        //  + workList.size() + " da 0 a " + (workList.size() - 1));

        while (workListIterator.hasNext()) {
            currElement = (KnuthElement) workListIterator.next();
            //log.debug("elemento n. " + workListIterator.previousIndex() 
            //  + " nella workList");
            if (prevElement != null
                && prevElement.getLayoutManager() != currElement.getLayoutManager()) {
                // prevElement is the last element generated by the same LM
                BlockLevelLayoutManager prevLM = (BlockLevelLayoutManager)
                                                 prevElement.getLayoutManager();
                BlockLevelLayoutManager currLM = (BlockLevelLayoutManager)
                                                 currElement.getLayoutManager();
                boolean bSomethingAdded = false;
                if (prevLM != this) {
                    //log.debug(" BLM.getChangedKnuthElements> chiamata da " 
                    //    + fromIndex + " a " + workListIterator.previousIndex() + " su " 
                    //    + prevLM.getClass().getName());
                    returnedList.addAll(prevLM.getChangedKnuthElements(workList.subList(
                                fromIndex, workListIterator.previousIndex()), alignment));
                    bSomethingAdded = true;
                } else {
                    // prevLM == this
                    // do nothing
                    //log.debug(" BLM.getChangedKnuthElements> elementi propri, "
                    //  + "ignorati, da " + fromIndex + " a " + workListIterator.previousIndex() 
                    //  + " su " + prevLM.getClass().getName());
                }
                fromIndex = workListIterator.previousIndex();

                /*
                 * TODO: why are KnuthPenalties added here,
                 *       while in getNextKE they were changed to BreakElements?
                 */
                // there is another block after this one
                if (bSomethingAdded
                    && (this.mustKeepTogether()
                        || prevLM.mustKeepWithNext()
                        || currLM.mustKeepWithPrevious())) {
                    // add an infinite penalty to forbid a break between blocks
                    returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, 
                            new Position(this), false));
                } else if (bSomethingAdded && !((KnuthElement) returnedList.getLast()).isGlue()) {
                    // add a null penalty to allow a break between blocks
                    returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
                }
            }
            prevElement = currElement;
        }
        if (currElement != null) {
            BlockLevelLayoutManager currLM = (BlockLevelLayoutManager)
                                             currElement.getLayoutManager();
            if (currLM != this) {
                //log.debug(" BLM.getChangedKnuthElements> chiamata da " + fromIndex 
                //  + " a " + oldList.size() + " su " + currLM.getClass().getName());
                returnedList.addAll(currLM.getChangedKnuthElements(
                        workList.subList(fromIndex, workList.size()), alignment));
            } else {
                // currLM == this
                // there are no more elements to add
                // remove the last penalty added to returnedList
                if (returnedList.size() > 0) {
                    returnedList.removeLast();
                }
                //log.debug(" BLM.getChangedKnuthElements> elementi propri, ignorati, da " 
                //  + fromIndex + " a " + workList.size());
            }
        }

        // append elements representing space-before
        boolean spaceBeforeIsConditional = true;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            spaceBeforeIsConditional = ((org.apache.fop.fo.flow.Block)fobj)
                    .getCommonMarginBlock().spaceBefore.getSpace().isDiscard();
        }
        if (bpUnit > 0
            || adjustedSpaceBefore != 0) {
            if (!spaceBeforeIsConditional) {
                // add elements to prevent the glue to be discarded
                returnList.add(new KnuthBox(0,
                                            new NonLeafPosition(this, null), false));
                returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                                new NonLeafPosition(this, null), false));
            }
            if (bpUnit > 0) {
                returnList.add(new KnuthGlue(0, 0, 0,
                    SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
            } else {
                returnList.add(new KnuthGlue(adjustedSpaceBefore, 0, 0,
                    SPACE_BEFORE_ADJUSTMENT, new NonLeafPosition(this, null), true));
            }
        }

        //log.debug("  BLM.getChangedKnuthElements> intermedio: returnedList.size() = " 
        //    + returnedList.size());

/* estensione: conversione complessiva */
/*LF*/  if (bpUnit > 0) {
/*LF*/      storedList = returnedList;
/*LF*/      returnedList = createUnitElements(returnedList);
/*LF*/  }
/* estensione */

        // "wrap" the Position stored in each element of returnedList
        // and add elements to returnList
        ListIterator listIter = returnedList.listIterator();
        while (listIter.hasNext()) {
            returnedElement = (KnuthElement)listIter.next();
            returnedElement.setPosition(new NonLeafPosition(this, returnedElement.getPosition()));
            returnList.add(returnedElement);
        }

        // append elements representing space-after
        boolean spaceAfterIsConditional = true;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            spaceAfterIsConditional = ((org.apache.fop.fo.flow.Block)fobj)
                        .getCommonMarginBlock().spaceAfter.getSpace().isDiscard();
        }
        if (bpUnit > 0 || adjustedSpaceAfter != 0) {
            if (!spaceAfterIsConditional) {
                returnList.add(new KnuthPenalty(0, 
                        KnuthElement.INFINITE, false,
                        new NonLeafPosition(this, null), false));
            }
            if (bpUnit > 0) {
                returnList.add(new KnuthGlue(0, 0, 0,
                        SPACE_AFTER_ADJUSTMENT, 
                        new NonLeafPosition(this, null),
                        (!spaceAfterIsConditional) ? false : true));
            } else {
                returnList.add(new KnuthGlue(adjustedSpaceAfter, 0, 0,
                        SPACE_AFTER_ADJUSTMENT, 
                        new NonLeafPosition(this, null),
                        (!spaceAfterIsConditional) ? false : true));
            }
            if (!spaceAfterIsConditional) {
                returnList.add(new KnuthBox(0,
                        new NonLeafPosition(this, null), true));
            }
        }

        //log.debug("  BLM.getChangedKnuthElements> finished: returnList.size() = " 
        //  + returnList.size());
        return returnList;
    }

    /**
     * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether()
     */
    // default action: ask parentLM
    public boolean mustKeepTogether() {
        return ((getParent() instanceof BlockLevelLayoutManager
                    && ((BlockLevelLayoutManager) getParent()).mustKeepTogether())
                || (getParent() instanceof InlineLayoutManager
                    && ((InlineLayoutManager) getParent()).mustKeepTogether()));
    }

    /**
     * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious()
     */
    public boolean mustKeepWithPrevious() {
        return false;
    }

    /**
     * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext()
     */
    public boolean mustKeepWithNext() {
        return false;
    }

    /**
     * Adds the unresolved elements for border and padding to a layout context so break
     * possibilities can be properly constructed.
     * @param context the layout context
     */
    protected void addPendingMarks(LayoutContext context) {
        CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
        if (borderAndPadding != null) {
            if (borderAndPadding.getBorderBeforeWidth(false) > 0) {
                context.addPendingBeforeMark(new BorderElement(
                        getAuxiliaryPosition(), 
                        borderAndPadding.getBorderInfo(
                                CommonBorderPaddingBackground.BEFORE).getWidth(),
                                RelSide.BEFORE,
                                false, false, this));
            }
            if (borderAndPadding.getPaddingBefore(false, this) > 0) {
                context.addPendingBeforeMark(new PaddingElement(
                        getAuxiliaryPosition(),
                        borderAndPadding.getPaddingLengthProperty(
                                CommonBorderPaddingBackground.BEFORE),
                                RelSide.BEFORE, 
                                false, false, this));
            }
            if (borderAndPadding.getBorderAfterWidth(false) > 0) {
                context.addPendingAfterMark(new BorderElement(
                        getAuxiliaryPosition(), 
                        borderAndPadding.getBorderInfo(
                                CommonBorderPaddingBackground.AFTER).getWidth(),
                                RelSide.AFTER, 
                                false, false, this));
            }
            if (borderAndPadding.getPaddingAfter(false, this) > 0) {
                context.addPendingAfterMark(new PaddingElement(
                        getAuxiliaryPosition(),
                        borderAndPadding.getPaddingLengthProperty(
                                CommonBorderPaddingBackground.AFTER),
                                RelSide.AFTER, 
                                false, false, this));
            }
        }
    }
    
    /** @return the border, padding and background info structure */
    private CommonBorderPaddingBackground getBorderPaddingBackground() {
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            return ((org.apache.fop.fo.flow.Block)fobj)
                .getCommonBorderPaddingBackground();
        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
            return ((org.apache.fop.fo.flow.BlockContainer)fobj)
                .getCommonBorderPaddingBackground();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
            return ((org.apache.fop.fo.flow.ListBlock)fobj)
                .getCommonBorderPaddingBackground();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
            return ((org.apache.fop.fo.flow.ListItem)fobj)
                .getCommonBorderPaddingBackground();
        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
            return ((org.apache.fop.fo.flow.Table)fobj)
                .getCommonBorderPaddingBackground();
        } else {
            return null;
        }
    }
    
    /** @return the space-before property */
    private SpaceProperty getSpaceBeforeProperty() {
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            return ((org.apache.fop.fo.flow.Block)fobj)
                .getCommonMarginBlock().spaceBefore;
        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
            return ((org.apache.fop.fo.flow.BlockContainer)fobj)
                .getCommonMarginBlock().spaceBefore;
        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
            return ((org.apache.fop.fo.flow.ListBlock)fobj)
                .getCommonMarginBlock().spaceBefore;
        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
            return ((org.apache.fop.fo.flow.ListItem)fobj)
                .getCommonMarginBlock().spaceBefore;
        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
            return ((org.apache.fop.fo.flow.Table)fobj)
                .getCommonMarginBlock().spaceBefore;
        } else {
            return null;
        }
    }
    
    /** @return the space-after property */
    private SpaceProperty getSpaceAfterProperty() {
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            return ((org.apache.fop.fo.flow.Block)fobj)
                .getCommonMarginBlock().spaceAfter;
        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
            return ((org.apache.fop.fo.flow.BlockContainer)fobj)
                .getCommonMarginBlock().spaceAfter;
        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
            return ((org.apache.fop.fo.flow.ListBlock)fobj)
                .getCommonMarginBlock().spaceAfter;
        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
            return ((org.apache.fop.fo.flow.ListItem)fobj)
                .getCommonMarginBlock().spaceAfter;
        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
            return ((org.apache.fop.fo.flow.Table)fobj)
                .getCommonMarginBlock().spaceAfter;
        } else {
            return null;
        }
    }
    
    /**
     * Creates Knuth elements for before border padding and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param isFirst true if this is the first time a layout manager instance needs to generate 
     *                border and padding
     */
    protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList, boolean isFirst) {
        //Border and Padding (before)
        CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
        if (borderAndPadding != null) {
            if (borderAndPadding.getBorderBeforeWidth(false) > 0) {
                returnList.add(new BorderElement(
                        getAuxiliaryPosition(), 
                        borderAndPadding.getBorderInfo(CommonBorderPaddingBackground.BEFORE)
                                .getWidth(),
                        RelSide.BEFORE, isFirst, false, this));
            }
            if (borderAndPadding.getPaddingBefore(false, this) > 0) {
                returnList.add(new PaddingElement(
                        getAuxiliaryPosition(),
                        borderAndPadding.getPaddingLengthProperty(
                                CommonBorderPaddingBackground.BEFORE), 
                        RelSide.BEFORE, isFirst, false, this));
            }
        }
    }

    /**
     * Creates Knuth elements for after border padding and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param isLast true if this is the last time a layout manager instance needs to generate 
     *               border and padding
     */
    protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList, boolean isLast) {
        //Border and Padding (after)
        CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
        if (borderAndPadding != null) {
            if (borderAndPadding.getPaddingAfter(false, this) > 0) {
                returnList.add(new PaddingElement(
                        getAuxiliaryPosition(),
                        borderAndPadding.getPaddingLengthProperty(
                                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, isLast, this));
            }
        }
    }

    /**
     * Creates Knuth elements for break-before and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param context the layout context
     * @return true if an element has been added due to a break-before.
     */
    protected boolean addKnuthElementsForBreakBefore(LinkedList returnList, 
            LayoutContext context) {
        int breakBefore = -1;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            breakBefore = ((org.apache.fop.fo.flow.Block) fobj).getBreakBefore();
        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
            breakBefore = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakBefore();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
            breakBefore = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakBefore();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
            breakBefore = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakBefore();
        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
            breakBefore = ((org.apache.fop.fo.flow.Table) fobj).getBreakBefore();
        }
        if (breakBefore == EN_PAGE
                || breakBefore == EN_COLUMN 
                || breakBefore == EN_EVEN_PAGE 
                || breakBefore == EN_ODD_PAGE) {
            // return a penalty element, representing a forced page break
            returnList.add(new BreakElement(getAuxiliaryPosition(), 
                    0, -KnuthElement.INFINITE, breakBefore, context));
            return true;
        } else {
            return false;
        }
    }

    /**
     * Creates Knuth elements for break-after and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param context the layout context
     * @return true if an element has been added due to a break-after.
     */
    protected boolean addKnuthElementsForBreakAfter(LinkedList returnList, 
            LayoutContext context) {
        int breakAfter = -1;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            breakAfter = ((org.apache.fop.fo.flow.Block) fobj).getBreakAfter();
        } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
            breakAfter = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakAfter();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListBlock) {
            breakAfter = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakAfter();
        } else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
            breakAfter = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakAfter();
        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
            breakAfter = ((org.apache.fop.fo.flow.Table) fobj).getBreakAfter();
        }
        if (breakAfter == EN_PAGE
                || breakAfter == EN_COLUMN
                || breakAfter == EN_EVEN_PAGE
                || breakAfter == EN_ODD_PAGE) {
            // add a penalty element, representing a forced page break
            returnList.add(new BreakElement(getAuxiliaryPosition(), 
                    0, -KnuthElement.INFINITE, breakAfter, context));
            return true;
        } else {
            return false;
        }
    }

    /**
     * Creates Knuth elements for space-before and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param alignment vertical alignment
     */
    protected void addKnuthElementsForSpaceBefore(LinkedList returnList/*, 
            Position returnPosition*/, int alignment) {
        SpaceProperty spaceBefore = getSpaceBeforeProperty();
        // append elements representing space-before
        if (spaceBefore != null
                   && !(spaceBefore.getMinimum(this).getLength().getValue(this) == 0 
                        && spaceBefore.getMaximum(this).getLength().getValue(this) == 0)) {
            returnList.add(new SpaceElement(getAuxiliaryPosition(), spaceBefore,
                    RelSide.BEFORE, 
                    true, false, this));
        }
        /*
        if (bpUnit > 0
                || spaceBefore != null
                   && !(spaceBefore.getMinimum(this).getLength().getValue(this) == 0 
                        && spaceBefore.getMaximum(this).getLength().getValue(this) == 0)) {
            if (spaceBefore != null && !spaceBefore.getSpace().isDiscard()) {
                // add elements to prevent the glue to be discarded
                returnList.add(new KnuthBox(0, getAuxiliaryPosition(), false));
                returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
                        false, getAuxiliaryPosition(), false));
            }
            if (bpUnit > 0) {
                returnList.add(new KnuthGlue(0, 0, 0,
                        BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
                        getAuxiliaryPosition(), true));
            } else { //if (alignment == EN_JUSTIFY) {
                returnList.add(new KnuthGlue(
                        spaceBefore.getOptimum(this).getLength().getValue(this),
                        spaceBefore.getMaximum(this).getLength().getValue(this)
                                - spaceBefore.getOptimum(this).getLength().getValue(this),
                        spaceBefore.getOptimum(this).getLength().getValue(this)
                                - spaceBefore.getMinimum(this).getLength().getValue(this),
                        BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
                        getAuxiliaryPosition(), true));
//            } else {
//                returnList.add(new KnuthGlue(
//                        spaceBefore.getOptimum().getLength().getValue(this), 
//                        0, 0, BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT,
//                        returnPosition, true));
            }
        }*/
    }

    /**
     * Creates Knuth elements for space-after and adds them to the return list.
     * @param returnList return list to add the additional elements to
     * @param alignment vertical alignment
     */
    protected void addKnuthElementsForSpaceAfter(LinkedList returnList/*, Position returnPosition*/, 
                int alignment) {
        SpaceProperty spaceAfter = getSpaceAfterProperty();
        // append elements representing space-after
        if (spaceAfter != null
                && !(spaceAfter.getMinimum(this).getLength().getValue(this) == 0 
                     && spaceAfter.getMaximum(this).getLength().getValue(this) == 0)) {
            returnList.add(new SpaceElement(getAuxiliaryPosition(), spaceAfter,
                    RelSide.AFTER, 
                    false, true, this));
        }
        /*
        if (bpUnit > 0
                || spaceAfter != null
                   && !(spaceAfter.getMinimum(this).getLength().getValue(this) == 0 
                        && spaceAfter.getMaximum(this).getLength().getValue(this) == 0)) {
            if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
                returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
                        false, getAuxiliaryPosition(), false));
            }
            if (bpUnit > 0) {
                returnList.add(new KnuthGlue(0, 0, 0, 
                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT,
                        getAuxiliaryPosition(), true));
            } else { //if (alignment == EN_JUSTIFY) {
                returnList.add(new KnuthGlue(
                        spaceAfter.getOptimum(this).getLength().getValue(this),
                        spaceAfter.getMaximum(this).getLength().getValue(this)
                                - spaceAfter.getOptimum(this).getLength().getValue(this),
                        spaceAfter.getOptimum(this).getLength().getValue(this)
                                - spaceAfter.getMinimum(this).getLength().getValue(this),
                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, getAuxiliaryPosition(),
                        (!spaceAfter.getSpace().isDiscard()) ? false : true));
//            } else {
//                returnList.add(new KnuthGlue(
//                        spaceAfter.getOptimum().getLength().getValue(this), 0, 0,
//                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, returnPosition,
//                        (!spaceAfter.getSpace().isDiscard()) ? false : true));
            }
            if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
                returnList.add(new KnuthBox(0, getAuxiliaryPosition(), true));
            }
        }*/
    }

    protected LinkedList createUnitElements(LinkedList oldList) {
        //log.debug("Start conversion: " + oldList.size() 
        //  + " elements, space-before.min=" + layoutProps.spaceBefore.getSpace().min
        //  + " space-after.min=" + layoutProps.spaceAfter.getSpace().min);
        // add elements at the beginning and at the end of oldList
        // representing minimum spaces
        LayoutManager lm = ((KnuthElement)oldList.getFirst()).getLayoutManager();
        boolean bAddedBoxBefore = false;
        boolean bAddedBoxAfter = false;
        if (adjustedSpaceBefore > 0) {
            oldList.addFirst(new KnuthBox(adjustedSpaceBefore,
                                          new Position(lm), true));
            bAddedBoxBefore = true;
        }
        if (adjustedSpaceAfter > 0) {
            oldList.addLast(new KnuthBox(adjustedSpaceAfter,
                                         new Position(lm), true));
            bAddedBoxAfter = true;
        }

        MinOptMax totalLength = new MinOptMax(0);
        MinOptMax totalUnits = new MinOptMax(0);
        LinkedList newList = new LinkedList();

        //log.debug(" Prima scansione");
        // scan the list once to compute total min, opt and max length
        ListIterator oldListIterator = oldList.listIterator();
        while (oldListIterator.hasNext()) {
            KnuthElement element = (KnuthElement) oldListIterator.next();
            if (element.isBox()) {
                totalLength.add(new MinOptMax(element.getW()));
                //log.debug("box " + element.getW());               
            } else if (element.isGlue()) {
                totalLength.min -= ((KnuthGlue) element).getZ();
                totalLength.max += ((KnuthGlue) element).getY();
                //leafValue = ((LeafPosition) element.getPosition()).getLeafPos();
                //log.debug("glue " + element.getW() + " + " 
                //    + ((KnuthGlue) element).getY() + " - " + ((KnuthGlue) element).getZ());
            } else {
                //log.debug((((KnuthPenalty)element).getP() == KnuthElement.INFINITE 
                //    ? "PENALTY " : "penalty ") + element.getW());
            }
        }
        // compute the total amount of "units"
        totalUnits = new MinOptMax(neededUnits(totalLength.min),
                                   neededUnits(totalLength.opt),
                                   neededUnits(totalLength.max));
        //log.debug(" totalLength= " + totalLength);
        //log.debug(" unita'= " + totalUnits);

        //log.debug(" Seconda scansione");
        // scan the list once more, stopping at every breaking point
        // in order to compute partial min, opt and max length
        // and create the new elements
        oldListIterator = oldList.listIterator();
        boolean bPrevIsBox = false;
        MinOptMax lengthBeforeBreak = new MinOptMax(0);
        MinOptMax lengthAfterBreak = (MinOptMax) totalLength.clone();
        MinOptMax unitsBeforeBreak;
        MinOptMax unitsAfterBreak;
        MinOptMax unsuppressibleUnits = new MinOptMax(0);
        int firstIndex = 0;
        int lastIndex = -1;
        while (oldListIterator.hasNext()) {
            KnuthElement element = (KnuthElement) oldListIterator.next();
            lastIndex++;
            if (element.isBox()) {
                lengthBeforeBreak.add(new MinOptMax(element.getW()));
                lengthAfterBreak.subtract(new MinOptMax(element.getW()));
                bPrevIsBox = true;
            } else if (element.isGlue()) {
                lengthBeforeBreak.min -= ((KnuthGlue) element).getZ();
                lengthAfterBreak.min += ((KnuthGlue) element).getZ();
                lengthBeforeBreak.max += ((KnuthGlue) element).getY();
                lengthAfterBreak.max -= ((KnuthGlue) element).getY();
                bPrevIsBox = false;
            } else {
                lengthBeforeBreak.add(new MinOptMax(element.getW()));
                bPrevIsBox = false;
            }

            // create the new elements
            if (element.isPenalty() && ((KnuthPenalty) element).getP() < KnuthElement.INFINITE
                    || element.isGlue() && bPrevIsBox
                    || !oldListIterator.hasNext()) {
                // suppress elements after the breaking point
                int iStepsForward = 0;
                while (oldListIterator.hasNext()) {
                    KnuthElement el = (KnuthElement) oldListIterator.next();
                    iStepsForward++;
                    if (el.isGlue()) {
                        // suppressed glue
                        lengthAfterBreak.min += ((KnuthGlue) el).getZ();
                        lengthAfterBreak.max -= ((KnuthGlue) el).getY();
                    } else if (el.isPenalty()) {
                        // suppressed penalty, do nothing
                    } else {
                        // box, end of suppressions
                        break;
                    }
                }
                // compute the partial amount of "units" before and after the break
                unitsBeforeBreak = new MinOptMax(neededUnits(lengthBeforeBreak.min),
                                                 neededUnits(lengthBeforeBreak.opt),
                                                 neededUnits(lengthBeforeBreak.max));
                unitsAfterBreak = new MinOptMax(neededUnits(lengthAfterBreak.min),
                                                neededUnits(lengthAfterBreak.opt),
                                                neededUnits(lengthAfterBreak.max));

                // rewind the iterator and lengthAfterBreak
                for (int i = 0; i < iStepsForward; i++) {
                    KnuthElement el = (KnuthElement) oldListIterator.previous();
                    if (el.isGlue()) {
                        lengthAfterBreak.min -= ((KnuthGlue) el).getZ();
                        lengthAfterBreak.max += ((KnuthGlue) el).getY();
                    }
                }

                // compute changes in length, stretch and shrink
                int uLengthChange = unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt;
                int uStretchChange = (unitsBeforeBreak.max + unitsAfterBreak.max - totalUnits.max)
                    - (unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt);
                int uShrinkChange = (unitsBeforeBreak.opt + unitsAfterBreak.opt - totalUnits.opt)
                    - (unitsBeforeBreak.min + unitsAfterBreak.min - totalUnits.min);

                // compute the number of normal, stretch and shrink unit
                // that must be added to the new sequence
                int uNewNormal = unitsBeforeBreak.opt - unsuppressibleUnits.opt;
                int uNewStretch = (unitsBeforeBreak.max - unitsBeforeBreak.opt)
                                  - (unsuppressibleUnits.max - unsuppressibleUnits.opt);
                int uNewShrink = (unitsBeforeBreak.opt - unitsBeforeBreak.min)
                                 - (unsuppressibleUnits.opt - unsuppressibleUnits.min);

                //log.debug("(" 
                //    + unsuppressibleUnits.min + "-" + unsuppressibleUnits.opt + "-" 
                //         + unsuppressibleUnits.max + ") "
                //    + " -> " + unitsBeforeBreak.min + "-" + unitsBeforeBreak.opt + "-" 
                //         + unitsBeforeBreak.max
                //    + " + " + unitsAfterBreak.min + "-" + unitsAfterBreak.opt + "-" 
                //         + unitsAfterBreak.max
                //    + (uLengthChange != 0 ? " [length " + uLengthChange + "] " : "")
                //    + (uStretchChange != 0 ? " [stretch " + uStretchChange + "] " : "")
                //    + (uShrinkChange != 0 ? " [shrink " + uShrinkChange + "]" : ""));

                // create the MappingPosition which will be stored in the new elements
                // correct firstIndex and lastIndex
                int firstIndexCorrection = 0;
                int lastIndexCorrection = 0;
                if (bAddedBoxBefore) {
                    if (firstIndex != 0) {
                        firstIndexCorrection++;
                    }
                    lastIndexCorrection++;
                }
                if (bAddedBoxAfter && lastIndex == (oldList.size() - 1)) {
                    lastIndexCorrection++;
                }
                MappingPosition mappingPos = new MappingPosition(this,
                                                                 firstIndex - firstIndexCorrection,
                                                                 lastIndex - lastIndexCorrection);

                // new box
                newList.add(new KnuthBox((uNewNormal - uLengthChange) * bpUnit,
                                         mappingPos,
                                         false));
                unsuppressibleUnits.add(new MinOptMax(uNewNormal - uLengthChange));
                //log.debug("        box " + (uNewNormal - uLengthChange));

                // new infinite penalty, glue and box, if necessary
                if (uNewStretch - uStretchChange > 0
                    || uNewShrink - uShrinkChange > 0) {
                    int iStretchUnits = (uNewStretch - uStretchChange > 0 
                            ? (uNewStretch - uStretchChange) : 0);
                    int iShrinkUnits = (uNewShrink - uShrinkChange > 0 
                            ? (uNewShrink - uShrinkChange) : 0);
                    newList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                                 mappingPos,
                                                 false));
                    newList.add(new KnuthGlue(0,
                                              iStretchUnits * bpUnit,
                                              iShrinkUnits * bpUnit,
                                              LINE_NUMBER_ADJUSTMENT,
                                              mappingPos,
                                              false));
                    //log.debug("        PENALTY");
                    //log.debug("        glue 0 " + iStretchUnits + " " + iShrinkUnits);
                    unsuppressibleUnits.max += iStretchUnits;
                    unsuppressibleUnits.min -= iShrinkUnits;
                    if (!oldListIterator.hasNext()) {
                        newList.add(new KnuthBox(0,
                                                 mappingPos,
                                                 false));
                        //log.debug("        box 0");
                    }
                }

                // new breaking sequence
                if (uStretchChange != 0
                    || uShrinkChange != 0) {
                    // new infinite penalty, glue, penalty and glue
                    newList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                                 mappingPos,
                                                 false));
                    newList.add(new KnuthGlue(0,
                                              uStretchChange * bpUnit,
                                              uShrinkChange * bpUnit,
                                              LINE_NUMBER_ADJUSTMENT,
                                              mappingPos,
                                              false));
                    newList.add(new KnuthPenalty(uLengthChange * bpUnit,
                                                 0, false, element.getPosition(), false));
                    newList.add(new KnuthGlue(0,
                                              -uStretchChange * bpUnit,
                                              -uShrinkChange * bpUnit,
                                              LINE_NUMBER_ADJUSTMENT,
                                              mappingPos,
                                              false));
                    //log.debug("        PENALTY");
                    //log.debug("        glue 0 " + uStretchChange + " " + uShrinkChange);
                    //log.debug("        penalty " + uLengthChange + " * unit");
                    //log.debug("        glue 0 " + (- uStretchChange) + " " 
                    //      + (- uShrinkChange));
                } else if (oldListIterator.hasNext()) {
                    // new penalty
                    newList.add(new KnuthPenalty(uLengthChange * bpUnit,
                                                 0, false,
                                                 mappingPos,
                                                 false));
                    //log.debug("        penalty " + uLengthChange + " * unit");
                }
                // update firstIndex
                firstIndex = lastIndex + 1;
            }

            if (element.isPenalty()) {
                lengthBeforeBreak.add(new MinOptMax(-element.getW()));
            }

        }

        // remove elements at the beginning and at the end of oldList
        // representing minimum spaces
        if (adjustedSpaceBefore > 0) {
            oldList.removeFirst();
        }
        if (adjustedSpaceAfter > 0) {
            oldList.removeLast();
        }

        // if space-before.conditionality is "discard", correct newList
        boolean correctFirstElement = false;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            correctFirstElement = ((org.apache.fop.fo.flow.Block)fobj)
                .getCommonMarginBlock().spaceBefore.getSpace().isDiscard();
        }
        if (correctFirstElement) {
            // remove the wrong element
            KnuthBox wrongBox = (KnuthBox) newList.removeFirst();
            // if this paragraph is at the top of a page, the space before
            // must be ignored; compute the length change
            int decreasedLength = (neededUnits(totalLength.opt)
                                   - neededUnits(totalLength.opt - adjustedSpaceBefore))
                                  * bpUnit;
            // insert the correct elements
            newList.addFirst(new KnuthBox(wrongBox.getW() - decreasedLength,
                                          wrongBox.getPosition(), false));
            newList.addFirst(new KnuthGlue(decreasedLength, 0, 0, SPACE_BEFORE_ADJUSTMENT,
                                           wrongBox.getPosition(), false));
            //log.debug("        rimosso box " + neededUnits(wrongBox.getW()));
            //log.debug("        aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
            //log.debug("        aggiunto box " + neededUnits(
            //       wrongBox.getW() - decreasedLength));
        }

        // if space-after.conditionality is "discard", correct newList
        boolean correctLastElement = false;
        if (fobj instanceof org.apache.fop.fo.flow.Block) {
            correctLastElement = ((org.apache.fop.fo.flow.Block)fobj)
                    .getCommonMarginBlock().spaceAfter.getSpace().isDiscard();
        }
        if (correctLastElement) {
            // remove the wrong element
            KnuthBox wrongBox = (KnuthBox) newList.removeLast();
            // if the old sequence is box(h) penalty(inf) glue(x,y,z) box(0)
            // (it cannot be parted and has some stretch or shrink)
            // the wrong box is the first one, not the last one
            LinkedList preserveList = new LinkedList();
            if (wrongBox.getW() == 0) {
                preserveList.add(wrongBox);
                preserveList.addFirst((KnuthGlue) newList.removeLast());
                preserveList.addFirst((KnuthPenalty) newList.removeLast());
                wrongBox = (KnuthBox) newList.removeLast();
            }

            // if this paragraph is at the bottom of a page, the space after
            // must be ignored; compute the length change
            int decreasedLength = (neededUnits(totalLength.opt)
                                   - neededUnits(totalLength.opt - adjustedSpaceAfter))
                                  * bpUnit;
            // insert the correct box
            newList.addLast(new KnuthBox(wrongBox.getW() - decreasedLength,
                                         wrongBox.getPosition(), false));
            // add preserved elements
            if (preserveList.size() > 0) {
                newList.addAll(preserveList);
            }
            // insert the correct glue
            newList.addLast(new KnuthGlue(decreasedLength, 0, 0, SPACE_AFTER_ADJUSTMENT,
                                          wrongBox.getPosition(), false));
            //log.debug("        rimosso box " + neededUnits(wrongBox.getW()));
            //log.debug("        aggiunto box " + neededUnits(
            //      wrongBox.getW() - decreasedLength));
            //log.debug("        aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
        }

        return newList;
    }

    protected static class StackingIter extends PositionIterator {
        StackingIter(Iterator parentIter) {
            super(parentIter);
        }
    
        protected LayoutManager getLM(Object nextObj) {
            return ((Position) nextObj).getLM();
        }
    
        protected Position getPos(Object nextObj) {
            return ((Position) nextObj);
        }
    }

    protected static class MappingPosition extends Position {
        private int iFirstIndex;
        private int iLastIndex;
    
        public MappingPosition(LayoutManager lm, int first, int last) {
            super(lm);
            iFirstIndex = first;
            iLastIndex = last;
        }
        
        public int getFirstIndex() {
            return iFirstIndex;
        }
        
        public int getLastIndex() {
            return iLastIndex;
        }
    }

    /**
     * "wrap" the Position inside each element moving the elements from 
     * SourceList to targetList
     * @param sourceList source list
     * @param targetList target list receiving the wrapped position elements
     */
    protected void wrapPositionElements(List sourceList, List targetList) {
        wrapPositionElements(sourceList, targetList, false);
    }
    
    /**
     * "wrap" the Position inside each element moving the elements from 
     * SourceList to targetList
     * @param sourceList source list
     * @param targetList target list receiving the wrapped position elements
     * @param force if true, every Position is wrapper regardless of its LM of origin
     */
    protected void wrapPositionElements(List sourceList, List targetList, boolean force) {
          
        ListIterator listIter = sourceList.listIterator();
        while (listIter.hasNext()) {
            ListElement tempElement;
            tempElement = (ListElement) listIter.next();
            if (force || tempElement.getLayoutManager() != this) {
                tempElement.setPosition(notifyPos(new NonLeafPosition(this,
                        tempElement.getPosition())));
            }
            targetList.add(tempElement);
        }
    }

    /** @return the sum of start-indent and end-indent */
    protected int getIPIndents() {
        return startIndent + endIndent;
    }
    
    /**
     * Returns the IPD of the content area
     * @return the IPD of the content area
     */
    public int getContentAreaIPD() {
        return contentAreaIPD;
    }
   
    /**
     * Sets the IPD of the content area
     * @param contentAreaIPD the IPD of the content area
     */
    protected void setContentAreaIPD(int contentAreaIPD) {
        this.contentAreaIPD = contentAreaIPD;
    }
    
    /**
     * Returns the BPD of the content area
     * @return the BPD of the content area
     */
    public int getContentAreaBPD() {
        return -1;
    }
    
}

