You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/02/20 02:55:49 UTC

svn commit: r746085 [1/2] - in /poi/trunk/src: java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ scratchpad/src/org/apache/poi/hslf/dev/ scratchpad/src/org/apache/poi/hslf/model/ scratchpad/src/org/apache/poi/hslf/record/ scratchpad/src/...

Author: josh
Date: Fri Feb 20 01:55:47 2009
New Revision: 746085

URL: http://svn.apache.org/viewvc?rev=746085&view=rev
Log:
More fixes to allow EscherContainerRecord to exclusively maintain 'child records' field. (due to r745976 / r746018)

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java
    poi/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Table.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java Fri Feb 20 01:55:47 2009
@@ -2023,7 +2023,7 @@
                 }
 
                 EscherDggRecord dgg = null;
-                for(Iterator it = cr.getChildRecords().iterator(); it.hasNext();) {
+                for(Iterator<EscherRecord> it = cr.getChildIterator(); it.hasNext();) {
                     Object er = it.next();
                     if(er instanceof EscherDggRecord) {
                         dgg = (EscherDggRecord)er;
@@ -2150,7 +2150,9 @@
         {
             bstoreContainer = new EscherContainerRecord();
             bstoreContainer.setRecordId( EscherContainerRecord.BSTORE_CONTAINER );
-            dggContainer.getChildRecords().add( 1, bstoreContainer );
+            List<EscherRecord> childRecords = dggContainer.getChildRecords();
+            childRecords.add(1, bstoreContainer);
+            dggContainer.setChildRecords(childRecords);
         }
         bstoreContainer.setOptions( (short) ( (escherBSERecords.size() << 4) | 0xF ) );
 
@@ -2285,18 +2287,18 @@
             dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
 
             EscherDgRecord dg = null;
-            for(Iterator it = escherContainer.getChildRecords().iterator(); it.hasNext();) {
-                Object er = it.next();
+            for(Iterator<EscherRecord> it = escherContainer.getChildIterator(); it.hasNext();) {
+                EscherRecord er = it.next();
                 if(er instanceof EscherDgRecord) {
                     dg = (EscherDgRecord)er;
                     //update id of the drawing in the cloned sheet
                     dg.setOptions( (short) ( dgId << 4 ) );
                 } else if (er instanceof EscherContainerRecord){
                     //recursively find shape records and re-generate shapeId
-                    ArrayList spRecords = new ArrayList();
+                    List<EscherRecord> spRecords = new ArrayList<EscherRecord>();
                     EscherContainerRecord cp = (EscherContainerRecord)er;
                     cp.getRecordsById(EscherSpRecord.RECORD_ID,  spRecords);
-                    for(Iterator spIt = spRecords.iterator(); spIt.hasNext();) {
+                    for(Iterator<EscherRecord> spIt = spRecords.iterator(); spIt.hasNext();) {
                         EscherSpRecord sp = (EscherSpRecord)spIt.next();
                         int shapeId = drawingManager.allocateShapeId((short)dgId, dg);
                         //allocateShapeId increments the number of shapes. roll back to the previous value

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java Fri Feb 20 01:55:47 2009
@@ -196,21 +196,20 @@
     public EscherRecord findFirstWithId(short id) {
     	return findFirstWithId(id, getEscherRecords());
     }
-    private EscherRecord findFirstWithId(short id, List records) {
+    private EscherRecord findFirstWithId(short id, List<EscherRecord> records) {
     	// Check at our level
-    	for(Iterator it = records.iterator(); it.hasNext();) {
-    		EscherRecord r = (EscherRecord)it.next();
+    	for(Iterator<EscherRecord> it = records.iterator(); it.hasNext();) {
+    		EscherRecord r = it.next();
     		if(r.getRecordId() == id) {
     			return r;
     		}
     	}
     	
     	// Then check our children in turn
-    	for(Iterator it = records.iterator(); it.hasNext();) {
-    		EscherRecord r = (EscherRecord)it.next();
+    	for(Iterator<EscherRecord> it = records.iterator(); it.hasNext();) {
+    		EscherRecord r = it.next();
     		if(r.isContainerRecord()) {
-    			EscherRecord found =
-    				findFirstWithId(id, r.getChildRecords());
+    			EscherRecord found = findFirstWithId(id, r.getChildRecords());
     			if(found != null) {
     				return found;
     			}

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java Fri Feb 20 01:55:47 2009
@@ -70,823 +70,822 @@
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class EscherAggregate extends AbstractEscherHolderRecord {
-    public static final short sid = 9876; // not a real sid - dummy value
-    private static POILogger log = POILogFactory.getLogger(EscherAggregate.class);
+	public static final short sid = 9876; // not a real sid - dummy value
+	private static POILogger log = POILogFactory.getLogger(EscherAggregate.class);
 
-    public static final short ST_MIN = (short) 0;
-    public static final short ST_NOT_PRIMATIVE = ST_MIN;
-    public static final short ST_RECTANGLE = (short) 1;
-    public static final short ST_ROUNDRECTANGLE = (short) 2;
-    public static final short ST_ELLIPSE = (short) 3;
-    public static final short ST_DIAMOND = (short) 4;
-    public static final short ST_ISOCELESTRIANGLE = (short) 5;
-    public static final short ST_RIGHTTRIANGLE = (short) 6;
-    public static final short ST_PARALLELOGRAM = (short) 7;
-    public static final short ST_TRAPEZOID = (short) 8;
-    public static final short ST_HEXAGON = (short) 9;
-    public static final short ST_OCTAGON = (short) 10;
-    public static final short ST_PLUS = (short) 11;
-    public static final short ST_STAR = (short) 12;
-    public static final short ST_ARROW = (short) 13;
-    public static final short ST_THICKARROW = (short) 14;
-    public static final short ST_HOMEPLATE = (short) 15;
-    public static final short ST_CUBE = (short) 16;
-    public static final short ST_BALLOON = (short) 17;
-    public static final short ST_SEAL = (short) 18;
-    public static final short ST_ARC = (short) 19;
-    public static final short ST_LINE = (short) 20;
-    public static final short ST_PLAQUE = (short) 21;
-    public static final short ST_CAN = (short) 22;
-    public static final short ST_DONUT = (short) 23;
-    public static final short ST_TEXTSIMPLE = (short) 24;
-    public static final short ST_TEXTOCTAGON = (short) 25;
-    public static final short ST_TEXTHEXAGON = (short) 26;
-    public static final short ST_TEXTCURVE = (short) 27;
-    public static final short ST_TEXTWAVE = (short) 28;
-    public static final short ST_TEXTRING = (short) 29;
-    public static final short ST_TEXTONCURVE = (short) 30;
-    public static final short ST_TEXTONRING = (short) 31;
-    public static final short ST_STRAIGHTCONNECTOR1 = (short) 32;
-    public static final short ST_BENTCONNECTOR2 = (short) 33;
-    public static final short ST_BENTCONNECTOR3 = (short) 34;
-    public static final short ST_BENTCONNECTOR4 = (short) 35;
-    public static final short ST_BENTCONNECTOR5 = (short) 36;
-    public static final short ST_CURVEDCONNECTOR2 = (short) 37;
-    public static final short ST_CURVEDCONNECTOR3 = (short) 38;
-    public static final short ST_CURVEDCONNECTOR4 = (short) 39;
-    public static final short ST_CURVEDCONNECTOR5 = (short) 40;
-    public static final short ST_CALLOUT1 = (short) 41;
-    public static final short ST_CALLOUT2 = (short) 42;
-    public static final short ST_CALLOUT3 = (short) 43;
-    public static final short ST_ACCENTCALLOUT1 = (short) 44;
-    public static final short ST_ACCENTCALLOUT2 = (short) 45;
-    public static final short ST_ACCENTCALLOUT3 = (short) 46;
-    public static final short ST_BORDERCALLOUT1 = (short) 47;
-    public static final short ST_BORDERCALLOUT2 = (short) 48;
-    public static final short ST_BORDERCALLOUT3 = (short) 49;
-    public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50;
-    public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51;
-    public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52;
-    public static final short ST_RIBBON = (short) 53;
-    public static final short ST_RIBBON2 = (short) 54;
-    public static final short ST_CHEVRON = (short) 55;
-    public static final short ST_PENTAGON = (short) 56;
-    public static final short ST_NOSMOKING = (short) 57;
-    public static final short ST_SEAL8 = (short) 58;
-    public static final short ST_SEAL16 = (short) 59;
-    public static final short ST_SEAL32 = (short) 60;
-    public static final short ST_WEDGERECTCALLOUT = (short) 61;
-    public static final short ST_WEDGERRECTCALLOUT = (short) 62;
-    public static final short ST_WEDGEELLIPSECALLOUT = (short) 63;
-    public static final short ST_WAVE = (short) 64;
-    public static final short ST_FOLDEDCORNER = (short) 65;
-    public static final short ST_LEFTARROW = (short) 66;
-    public static final short ST_DOWNARROW = (short) 67;
-    public static final short ST_UPARROW = (short) 68;
-    public static final short ST_LEFTRIGHTARROW = (short) 69;
-    public static final short ST_UPDOWNARROW = (short) 70;
-    public static final short ST_IRREGULARSEAL1 = (short) 71;
-    public static final short ST_IRREGULARSEAL2 = (short) 72;
-    public static final short ST_LIGHTNINGBOLT = (short) 73;
-    public static final short ST_HEART = (short) 74;
-    public static final short ST_PICTUREFRAME = (short) 75;
-    public static final short ST_QUADARROW = (short) 76;
-    public static final short ST_LEFTARROWCALLOUT = (short) 77;
-    public static final short ST_RIGHTARROWCALLOUT = (short) 78;
-    public static final short ST_UPARROWCALLOUT = (short) 79;
-    public static final short ST_DOWNARROWCALLOUT = (short) 80;
-    public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81;
-    public static final short ST_UPDOWNARROWCALLOUT = (short) 82;
-    public static final short ST_QUADARROWCALLOUT = (short) 83;
-    public static final short ST_BEVEL = (short) 84;
-    public static final short ST_LEFTBRACKET = (short) 85;
-    public static final short ST_RIGHTBRACKET = (short) 86;
-    public static final short ST_LEFTBRACE = (short) 87;
-    public static final short ST_RIGHTBRACE = (short) 88;
-    public static final short ST_LEFTUPARROW = (short) 89;
-    public static final short ST_BENTUPARROW = (short) 90;
-    public static final short ST_BENTARROW = (short) 91;
-    public static final short ST_SEAL24 = (short) 92;
-    public static final short ST_STRIPEDRIGHTARROW = (short) 93;
-    public static final short ST_NOTCHEDRIGHTARROW = (short) 94;
-    public static final short ST_BLOCKARC = (short) 95;
-    public static final short ST_SMILEYFACE = (short) 96;
-    public static final short ST_VERTICALSCROLL = (short) 97;
-    public static final short ST_HORIZONTALSCROLL = (short) 98;
-    public static final short ST_CIRCULARARROW = (short) 99;
-    public static final short ST_NOTCHEDCIRCULARARROW = (short) 100;
-    public static final short ST_UTURNARROW = (short) 101;
-    public static final short ST_CURVEDRIGHTARROW = (short) 102;
-    public static final short ST_CURVEDLEFTARROW = (short) 103;
-    public static final short ST_CURVEDUPARROW = (short) 104;
-    public static final short ST_CURVEDDOWNARROW = (short) 105;
-    public static final short ST_CLOUDCALLOUT = (short) 106;
-    public static final short ST_ELLIPSERIBBON = (short) 107;
-    public static final short ST_ELLIPSERIBBON2 = (short) 108;
-    public static final short ST_FLOWCHARTPROCESS = (short) 109;
-    public static final short ST_FLOWCHARTDECISION = (short) 110;
-    public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111;
-    public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112;
-    public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113;
-    public static final short ST_FLOWCHARTDOCUMENT = (short) 114;
-    public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115;
-    public static final short ST_FLOWCHARTTERMINATOR = (short) 116;
-    public static final short ST_FLOWCHARTPREPARATION = (short) 117;
-    public static final short ST_FLOWCHARTMANUALINPUT = (short) 118;
-    public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119;
-    public static final short ST_FLOWCHARTCONNECTOR = (short) 120;
-    public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121;
-    public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122;
-    public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123;
-    public static final short ST_FLOWCHARTOR = (short) 124;
-    public static final short ST_FLOWCHARTCOLLATE = (short) 125;
-    public static final short ST_FLOWCHARTSORT = (short) 126;
-    public static final short ST_FLOWCHARTEXTRACT = (short) 127;
-    public static final short ST_FLOWCHARTMERGE = (short) 128;
-    public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129;
-    public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130;
-    public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131;
-    public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132;
-    public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133;
-    public static final short ST_FLOWCHARTDISPLAY = (short) 134;
-    public static final short ST_FLOWCHARTDELAY = (short) 135;
-    public static final short ST_TEXTPLAINTEXT = (short) 136;
-    public static final short ST_TEXTSTOP = (short) 137;
-    public static final short ST_TEXTTRIANGLE = (short) 138;
-    public static final short ST_TEXTTRIANGLEINVERTED = (short) 139;
-    public static final short ST_TEXTCHEVRON = (short) 140;
-    public static final short ST_TEXTCHEVRONINVERTED = (short) 141;
-    public static final short ST_TEXTRINGINSIDE = (short) 142;
-    public static final short ST_TEXTRINGOUTSIDE = (short) 143;
-    public static final short ST_TEXTARCHUPCURVE = (short) 144;
-    public static final short ST_TEXTARCHDOWNCURVE = (short) 145;
-    public static final short ST_TEXTCIRCLECURVE = (short) 146;
-    public static final short ST_TEXTBUTTONCURVE = (short) 147;
-    public static final short ST_TEXTARCHUPPOUR = (short) 148;
-    public static final short ST_TEXTARCHDOWNPOUR = (short) 149;
-    public static final short ST_TEXTCIRCLEPOUR = (short) 150;
-    public static final short ST_TEXTBUTTONPOUR = (short) 151;
-    public static final short ST_TEXTCURVEUP = (short) 152;
-    public static final short ST_TEXTCURVEDOWN = (short) 153;
-    public static final short ST_TEXTCASCADEUP = (short) 154;
-    public static final short ST_TEXTCASCADEDOWN = (short) 155;
-    public static final short ST_TEXTWAVE1 = (short) 156;
-    public static final short ST_TEXTWAVE2 = (short) 157;
-    public static final short ST_TEXTWAVE3 = (short) 158;
-    public static final short ST_TEXTWAVE4 = (short) 159;
-    public static final short ST_TEXTINFLATE = (short) 160;
-    public static final short ST_TEXTDEFLATE = (short) 161;
-    public static final short ST_TEXTINFLATEBOTTOM = (short) 162;
-    public static final short ST_TEXTDEFLATEBOTTOM = (short) 163;
-    public static final short ST_TEXTINFLATETOP = (short) 164;
-    public static final short ST_TEXTDEFLATETOP = (short) 165;
-    public static final short ST_TEXTDEFLATEINFLATE = (short) 166;
-    public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167;
-    public static final short ST_TEXTFADERIGHT = (short) 168;
-    public static final short ST_TEXTFADELEFT = (short) 169;
-    public static final short ST_TEXTFADEUP = (short) 170;
-    public static final short ST_TEXTFADEDOWN = (short) 171;
-    public static final short ST_TEXTSLANTUP = (short) 172;
-    public static final short ST_TEXTSLANTDOWN = (short) 173;
-    public static final short ST_TEXTCANUP = (short) 174;
-    public static final short ST_TEXTCANDOWN = (short) 175;
-    public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176;
-    public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177;
-    public static final short ST_CALLOUT90 = (short) 178;
-    public static final short ST_ACCENTCALLOUT90 = (short) 179;
-    public static final short ST_BORDERCALLOUT90 = (short) 180;
-    public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181;
-    public static final short ST_LEFTRIGHTUPARROW = (short) 182;
-    public static final short ST_SUN = (short) 183;
-    public static final short ST_MOON = (short) 184;
-    public static final short ST_BRACKETPAIR = (short) 185;
-    public static final short ST_BRACEPAIR = (short) 186;
-    public static final short ST_SEAL4 = (short) 187;
-    public static final short ST_DOUBLEWAVE = (short) 188;
-    public static final short ST_ACTIONBUTTONBLANK = (short) 189;
-    public static final short ST_ACTIONBUTTONHOME = (short) 190;
-    public static final short ST_ACTIONBUTTONHELP = (short) 191;
-    public static final short ST_ACTIONBUTTONINFORMATION = (short) 192;
-    public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193;
-    public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194;
-    public static final short ST_ACTIONBUTTONEND = (short) 195;
-    public static final short ST_ACTIONBUTTONBEGINNING = (short) 196;
-    public static final short ST_ACTIONBUTTONRETURN = (short) 197;
-    public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198;
-    public static final short ST_ACTIONBUTTONSOUND = (short) 199;
-    public static final short ST_ACTIONBUTTONMOVIE = (short) 200;
-    public static final short ST_HOSTCONTROL = (short) 201;
-    public static final short ST_TEXTBOX = (short) 202;
-    public static final short ST_NIL = (short) 0x0FFF;
-
-    protected HSSFPatriarch patriarch;
-
-    /** Maps shape container objects to their OBJ records */
-    private Map shapeToObj = new HashMap();
-    private DrawingManager2 drawingManager;
-    private short drawingGroupId;
-
-    /**
-     * list of "tail" records that need to be serialized after all drawing group records
-     */
-    private List tailRec = new ArrayList();
-
-    public EscherAggregate( DrawingManager2 drawingManager )
-    {
-        this.drawingManager = drawingManager;
-    }
-
-    /**
-     * @return  Returns the current sid.
-     */
-    public short getSid()
-    {
-        return sid;
-    }
-
-    /**
-     * Calculates the string representation of this record.  This is
-     * simply a dump of all the records.
-     */
-    public String toString()
-    {
-        String nl = System.getProperty( "line.separtor" );
-
-        StringBuffer result = new StringBuffer();
-        result.append( '[' ).append( getRecordName() ).append( ']' + nl );
-        for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord escherRecord = (EscherRecord) iterator.next();
-            result.append( escherRecord.toString() );
-        }
-        result.append( "[/" ).append( getRecordName() ).append( ']' + nl );
-
-        return result.toString();
-    }
-
-    /**
-     * Collapses the drawing records into an aggregate.
-     */
-    public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager2 drawingManager )
-    {
-        // Keep track of any shape records created so we can match them back to the object id's.
-        // Textbox objects are also treated as shape objects.
-        final List shapeRecords = new ArrayList();
-        EscherRecordFactory recordFactory = new DefaultEscherRecordFactory()
-        {
-            public EscherRecord createRecord( byte[] data, int offset )
-            {
-                EscherRecord r = super.createRecord( data, offset );
-                if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID )
-                {
-                    shapeRecords.add( r );
-                }
-                return r;
-            }
-        };
-
-        // Calculate the size of the buffer
-        EscherAggregate agg = new EscherAggregate(drawingManager);
-        int loc = locFirstDrawingRecord;
-        int dataSize = 0;
-        while ( loc + 1 < records.size()
-                && sid( records, loc ) == DrawingRecord.sid
-                && isObjectRecord( records, loc + 1 ) )
-        {
-            dataSize += ( (DrawingRecord) records.get( loc ) ).getData().length;
-            loc += 2;
-        }
-
-        // Create one big buffer
-        byte buffer[] = new byte[dataSize];
-        int offset = 0;
-        loc = locFirstDrawingRecord;
-        while ( loc + 1 < records.size()
-                && sid( records, loc ) == DrawingRecord.sid
-                && isObjectRecord( records, loc + 1 ) )
-        {
-            DrawingRecord drawingRecord = (DrawingRecord) records.get( loc );
-            System.arraycopy( drawingRecord.getData(), 0, buffer, offset, drawingRecord.getData().length );
-            offset += drawingRecord.getData().length;
-            loc += 2;
-        }
-
-        // Decode the shapes
-        //        agg.escherRecords = new ArrayList();
-        int pos = 0;
-        while ( pos < dataSize )
-        {
-            EscherRecord r = recordFactory.createRecord( buffer, pos );
-            int bytesRead = r.fillFields( buffer, pos, recordFactory );
-            agg.addEscherRecord( r );
-            pos += bytesRead;
-        }
-
-        // Associate the object records with the shapes
-        loc = locFirstDrawingRecord;
-        int shapeIndex = 0;
-        agg.shapeToObj = new HashMap();
-        while ( loc + 1 < records.size()
-                && sid( records, loc ) == DrawingRecord.sid
-                && isObjectRecord( records, loc + 1 ) )
-        {
-            Record objRecord = (Record) records.get( loc + 1 );
-            agg.shapeToObj.put( shapeRecords.get( shapeIndex++ ), objRecord );
-            loc += 2;
-        }
-
-        return agg;
-
-    }
-
-    /**
-     * Serializes this aggregate to a byte array.  Since this is an aggregate
-     * record it will effectively serialize the aggregated records.
-     *
-     * @param offset    The offset into the start of the array.
-     * @param data      The byte array to serialize to.
-     * @return          The number of bytes serialized.
-     */
-    public int serialize( int offset, byte[] data )
-    {
-        convertUserModelToRecords();
-
-        // Determine buffer size
-        List records = getEscherRecords();
-        int size = getEscherRecordSize( records );
-        byte[] buffer = new byte[size];
-
-
-        // Serialize escher records into one big data structure and keep note of ending offsets.
-        final List spEndingOffsets = new ArrayList();
-        final List shapes = new ArrayList();
-        int pos = 0;
-        for ( Iterator iterator = records.iterator(); iterator.hasNext(); )
-        {
-            EscherRecord e = (EscherRecord) iterator.next();
-            pos += e.serialize( pos, buffer, new EscherSerializationListener()
-            {
-                public void beforeRecordSerialize( int offset, short recordId, EscherRecord record )
-                {
-                }
-
-                public void afterRecordSerialize( int offset, short recordId, int size, EscherRecord record )
-                {
-                    if ( recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID )
-                    {
-                        spEndingOffsets.add( new Integer( offset ) );
-                        shapes.add( record );
-                    }
-                }
-            } );
-        }
-        // todo: fix this
-        shapes.add( 0, null );
-        spEndingOffsets.add( 0, null );
-
-        // Split escher records into separate MSODRAWING and OBJ, TXO records.  (We don't break on
-        // the first one because it's the patriach).
-        pos = offset;
-        for ( int i = 1; i < shapes.size(); i++ )
-        {
-            int endOffset = ( (Integer) spEndingOffsets.get( i ) ).intValue() - 1;
-            int startOffset;
-            if ( i == 1 )
-                startOffset = 0;
-            else
-                startOffset = ( (Integer) spEndingOffsets.get( i - 1 ) ).intValue();
-
-            // Create and write a new MSODRAWING record
-            DrawingRecord drawing = new DrawingRecord();
-            byte[] drawingData = new byte[endOffset - startOffset + 1];
-            System.arraycopy( buffer, startOffset, drawingData, 0, drawingData.length );
-            drawing.setData( drawingData );
-            int temp = drawing.serialize( pos, data );
-            pos += temp;
-
-            // Write the matching OBJ record
-            Record obj = (Record) shapeToObj.get( shapes.get( i ) );
-            temp = obj.serialize( pos, data );
-            pos += temp;
-
-        }
-
-        // write records that need to be serialized after all drawing group records
-        for ( int i = 0; i < tailRec.size(); i++ )
-        {
-            Record rec = (Record)tailRec.get(i);
-            pos += rec.serialize( pos, data );
-        }
-
-        int bytesWritten = pos - offset;
-        if ( bytesWritten != getRecordSize() )
-            throw new RecordFormatException( bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize() );
-        return bytesWritten;
-    }
-
-    /**
-     * How many bytes do the raw escher records contain.
-     * @param records   List of escher records
-     * @return  the number of bytes
-     */
-    private int getEscherRecordSize( List records )
-    {
-        int size = 0;
-        for ( Iterator iterator = records.iterator(); iterator.hasNext(); )
-            size += ( (EscherRecord) iterator.next() ).getRecordSize();
-        return size;
-    }
-
-    public int getRecordSize() {
-        // TODO - convert this to RecordAggregate
-        convertUserModelToRecords();
-        List records = getEscherRecords();
-        int rawEscherSize = getEscherRecordSize( records );
-        int drawingRecordSize = rawEscherSize + ( shapeToObj.size() ) * 4;
-        int objRecordSize = 0;
-        for ( Iterator iterator = shapeToObj.values().iterator(); iterator.hasNext(); )
-        {
-            Record r = (Record) iterator.next();
-            objRecordSize += r.getRecordSize();
-        }
-        int tailRecordSize = 0;
-        for ( Iterator iterator = tailRec.iterator(); iterator.hasNext(); )
-        {
-            Record r = (Record) iterator.next();
-            tailRecordSize += r.getRecordSize();
-        }
-        return drawingRecordSize + objRecordSize + tailRecordSize;
-    }
-
-    /**
-     * Associates an escher record to an OBJ record or a TXO record.
-     */
-    public Object assoicateShapeToObjRecord( EscherRecord r, Record objRecord )
-    {
-        return shapeToObj.put( r, objRecord );
-    }
-
-    public HSSFPatriarch getPatriarch()
-    {
-        return patriarch;
-    }
-
-    public void setPatriarch( HSSFPatriarch patriarch )
-    {
-        this.patriarch = patriarch;
-    }
-    
-    /**
-     * Converts the Records into UserModel
-     *  objects on the bound HSSFPatriarch
-     */
-    public void convertRecordsToUserModel() {
-    	if(patriarch == null) {
-    		throw new IllegalStateException("Must call setPatriarch() first");
-    	}
-    	
-    	// The top level container ought to have
-    	//  the DgRecord and the container of one container
-    	//  per shape group (patriach overall first)
-    	EscherContainerRecord topContainer = getEscherContainer();
-    	if(topContainer == null) {
-    		return;
-    	}
-    	topContainer = (EscherContainerRecord) 
-    		topContainer.getChildContainers().get(0);
-    	
-    	List tcc = topContainer.getChildContainers();
-    	if(tcc.size() == 0) {
-    		throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!");
-    	}
-    	
-    	// First up, get the patriach position
-    	// This is in the first EscherSpgrRecord, in
-    	//  the first container, with a EscherSRecord too
-    	EscherContainerRecord patriachContainer =
-    		(EscherContainerRecord)tcc.get(0);
-    	EscherSpgrRecord spgr = null;
-    	for(Iterator it = patriachContainer.getChildRecords().iterator(); it.hasNext();) {
-    		EscherRecord r = (EscherRecord)it.next();
-    		if(r instanceof EscherSpgrRecord) {
-    			spgr = (EscherSpgrRecord)r;
-    			break;
-    		}
-    	}
-    	if(spgr != null) {
-    		patriarch.setCoordinates(
-    				spgr.getRectX1(), spgr.getRectY1(),
-    				spgr.getRectX2(), spgr.getRectY2()
-    		);
-    	}
-    	
-    	// Now process the containers for each group
-    	//  and objects
-    	for(int i=1; i<tcc.size(); i++) {
-    		EscherContainerRecord shapeContainer =
-    			(EscherContainerRecord)tcc.get(i);
-    		//System.err.println("\n\n*****\n\n");
-    		//System.err.println(shapeContainer);
-    		
-    		// Could be a group, or a base object
-    		if(shapeContainer.getChildRecords().size() == 1 &&
-    				shapeContainer.getChildContainers().size() == 1) {
-    			// Group
-    			HSSFShapeGroup group =
-    				new HSSFShapeGroup(null, new HSSFClientAnchor());
-    			patriarch.getChildren().add(group);
-    			
-    			EscherContainerRecord groupContainer =
-    				(EscherContainerRecord)shapeContainer.getChild(0);
-    			convertRecordsToUserModel(groupContainer, group);
-    		} else if(shapeContainer.hasChildOfType((short)0xF00D)) {
-    			// TextBox
-    			HSSFTextbox box =
-    				new HSSFTextbox(null, new HSSFClientAnchor());
-    			patriarch.getChildren().add(box);
-    			
-    			convertRecordsToUserModel(shapeContainer, box);
-    		} else if(shapeContainer.hasChildOfType((short)0xF011)) {
-    			// Not yet supporting EscherClientDataRecord stuff
-    		} else {
-    			// Base level
-    			convertRecordsToUserModel(shapeContainer, patriarch);
-    		}
-    	}
-    	
-    	// Now, clear any trace of what records make up
-    	//  the patriarch
-    	// Otherwise, everything will go horribly wrong
-    	//  when we try to write out again....
-//    	clearEscherRecords();
-    	drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]);
-
-    	// TODO: Support converting our records
-    	//  back into shapes
-    	log.log(POILogger.WARN, "Not processing objects into Patriarch!");
-    }
-    
-    private void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) {
-    	for(Iterator it = shapeContainer.getChildRecords().iterator(); it.hasNext();) {
-    		EscherRecord r = (EscherRecord)it.next();
-    		if(r instanceof EscherSpgrRecord) {
-    			// This may be overriden by a later EscherClientAnchorRecord
-    			EscherSpgrRecord spgr = (EscherSpgrRecord)r;
-    			
-    			if(model instanceof HSSFShapeGroup) {
-    				HSSFShapeGroup g = (HSSFShapeGroup)model;
-    				g.setCoordinates(
-    						spgr.getRectX1(), spgr.getRectY1(),
-    						spgr.getRectX2(), spgr.getRectY2()
-    				);
-    			} else {
-    				throw new IllegalStateException("Got top level anchor but not processing a group");
-    			}
-    		} 
-    		else if(r instanceof EscherClientAnchorRecord) {
-    			EscherClientAnchorRecord car = (EscherClientAnchorRecord)r;
-    			
-    			if(model instanceof HSSFShape) {
-    				HSSFShape g = (HSSFShape)model;
-    				g.getAnchor().setDx1(car.getDx1());
-    				g.getAnchor().setDx2(car.getDx2());
-    				g.getAnchor().setDy1(car.getDy1());
-    				g.getAnchor().setDy2(car.getDy2());
-    			} else {
-    				throw new IllegalStateException("Got top level anchor but not processing a group or shape");
-    			}
-    		}
-    		else if(r instanceof EscherTextboxRecord) {
-    			EscherTextboxRecord tbr = (EscherTextboxRecord)r;
-    			
-    			// Also need to find the TextObjectRecord too
-    			// TODO
-    		}
-    		else if(r instanceof EscherSpRecord) {
-    			// Use flags if needed
-    		}
-    		else if(r instanceof EscherOptRecord) {
-    			// Use properties if needed
-    		}
-    		else {
-    			//System.err.println(r);
-    		}
-    	}
-    }
-    
-    public void clear()
-    {
-        clearEscherRecords();
-        shapeToObj.clear();
-//        lastShapeId = 1024;
-    }
-
-    protected String getRecordName()
-    {
-        return "ESCHERAGGREGATE";
-    }
-
-    // =============== Private methods ========================
-
-    private static boolean isObjectRecord( List records, int loc )
-    {
-        return sid( records, loc ) == ObjRecord.sid || sid( records, loc ) == TextObjectRecord.sid;
-    }
-
-    private void convertUserModelToRecords()
-    {
-        if ( patriarch != null )
-        {
-            shapeToObj.clear();
-            tailRec.clear();
-            clearEscherRecords();
-            if ( patriarch.getChildren().size() != 0 )
-            {
-                convertPatriarch( patriarch );
-                EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord( 0 );
-                EscherContainerRecord spgrContainer = null;
-                for ( int i = 0; i < dgContainer.getChildRecords().size(); i++ )
-                    if ( dgContainer.getChild( i ).getRecordId() == EscherContainerRecord.SPGR_CONTAINER )
-                        spgrContainer = (EscherContainerRecord) dgContainer.getChild( i );
-                convertShapes( patriarch, spgrContainer, shapeToObj );
-
-                patriarch = null;
-            }
-        }
-    }
-
-    private void convertShapes( HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj )
-    {
-        if ( escherParent == null ) throw new IllegalArgumentException( "Parent record required" );
-
-        List shapes = parent.getChildren();
-        for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
-        {
-            HSSFShape shape = (HSSFShape) iterator.next();
-            if ( shape instanceof HSSFShapeGroup )
-            {
-                convertGroup( (HSSFShapeGroup) shape, escherParent, shapeToObj );
-            }
-            else
-            {
-                AbstractShape shapeModel = AbstractShape.createShape(
-                        shape,
-                        drawingManager.allocateShapeId(drawingGroupId) );
-                shapeToObj.put( findClientData( shapeModel.getSpContainer() ), shapeModel.getObjRecord() );
-                if ( shapeModel instanceof TextboxShape )
-                {
-                    EscherRecord escherTextbox = ( (TextboxShape) shapeModel ).getEscherTextbox();
-                    shapeToObj.put( escherTextbox, ( (TextboxShape) shapeModel ).getTextObjectRecord() );
-                    //                    escherParent.addChildRecord(escherTextbox);
-                    
-                    if ( shapeModel instanceof CommentShape ){
-                        CommentShape comment = (CommentShape)shapeModel;
-                        tailRec.add(comment.getNoteRecord());
-                    }
-
-                }
-                escherParent.addChildRecord( shapeModel.getSpContainer() );
-            }
-        }
-//        drawingManager.newCluster( (short)1 );
-//        drawingManager.newCluster( (short)2 );
-
-    }
-
-    private void convertGroup( HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj )
-    {
-        EscherContainerRecord spgrContainer = new EscherContainerRecord();
-        EscherContainerRecord spContainer = new EscherContainerRecord();
-        EscherSpgrRecord spgr = new EscherSpgrRecord();
-        EscherSpRecord sp = new EscherSpRecord();
-        EscherOptRecord opt = new EscherOptRecord();
-        EscherRecord anchor;
-        EscherClientDataRecord clientData = new EscherClientDataRecord();
-
-        spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER );
-        spgrContainer.setOptions( (short) 0x000F );
-        spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
-        spContainer.setOptions( (short) 0x000F );
-        spgr.setRecordId( EscherSpgrRecord.RECORD_ID );
-        spgr.setOptions( (short) 0x0001 );
-        spgr.setRectX1( shape.getX1() );
-        spgr.setRectY1( shape.getY1() );
-        spgr.setRectX2( shape.getX2() );
-        spgr.setRectY2( shape.getY2() );
-        sp.setRecordId( EscherSpRecord.RECORD_ID );
-        sp.setOptions( (short) 0x0002 );
-        int shapeId = drawingManager.allocateShapeId(drawingGroupId);
-        sp.setShapeId( shapeId );
-        if (shape.getAnchor() instanceof HSSFClientAnchor)
-            sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR );
-        else
-            sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD );
-        opt.setRecordId( EscherOptRecord.RECORD_ID );
-        opt.setOptions( (short) 0x0023 );
-        opt.addEscherProperty( new EscherBoolProperty( EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004 ) );
-        opt.addEscherProperty( new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x00080000 ) );
-
-        anchor = ConvertAnchor.createAnchor( shape.getAnchor() );
-//        clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() );
-//        clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() );
-//        clientAnchor.setDx1( (short) shape.getAnchor().getDx1() );
-//        clientAnchor.setDy1( (short) shape.getAnchor().getDy1() );
-//        clientAnchor.setCol2( ( (HSSFClientAnchor) shape.getAnchor() ).getCol2() );
-//        clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() );
-//        clientAnchor.setDx2( (short) shape.getAnchor().getDx2() );
-//        clientAnchor.setDy2( (short) shape.getAnchor().getDy2() );
-        clientData.setRecordId( EscherClientDataRecord.RECORD_ID );
-        clientData.setOptions( (short) 0x0000 );
-
-        spgrContainer.addChildRecord( spContainer );
-        spContainer.addChildRecord( spgr );
-        spContainer.addChildRecord( sp );
-        spContainer.addChildRecord( opt );
-        spContainer.addChildRecord( anchor );
-        spContainer.addChildRecord( clientData );
-
-        ObjRecord obj = new ObjRecord();
-        CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
-        cmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_GROUP );
-        cmo.setObjectId( (short) ( shapeId ) );
-        cmo.setLocked( true );
-        cmo.setPrintable( true );
-        cmo.setAutofill( true );
-        cmo.setAutoline( true );
-        GroupMarkerSubRecord gmo = new GroupMarkerSubRecord();
-        EndSubRecord end = new EndSubRecord();
-        obj.addSubRecord( cmo );
-        obj.addSubRecord( gmo );
-        obj.addSubRecord( end );
-        shapeToObj.put( clientData, obj );
-
-        escherParent.addChildRecord( spgrContainer );
-
-        convertShapes( shape, spgrContainer, shapeToObj );
-
-    }
-
-    private EscherRecord findClientData( EscherContainerRecord spContainer )
-    {
-        for ( Iterator iterator = spContainer.getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
-            if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID )
-                return r;
-        }
-        throw new IllegalArgumentException( "Can not find client data record" );
-    }
-
-    private void convertPatriarch( HSSFPatriarch patriarch )
-    {
-        EscherContainerRecord dgContainer = new EscherContainerRecord();
-        EscherDgRecord dg;
-        EscherContainerRecord spgrContainer = new EscherContainerRecord();
-        EscherContainerRecord spContainer1 = new EscherContainerRecord();
-        EscherSpgrRecord spgr = new EscherSpgrRecord();
-        EscherSpRecord sp1 = new EscherSpRecord();
-
-        dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER );
-        dgContainer.setOptions( (short) 0x000F );
-        dg = drawingManager.createDgRecord();
-        drawingGroupId = dg.getDrawingGroupId();
-//        dg.setOptions( (short) ( drawingId << 4 ) );
-//        dg.setNumShapes( getNumberOfShapes( patriarch ) );
-//        dg.setLastMSOSPID( 0 );  // populated after all shape id's are assigned.
-        spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER );
-        spgrContainer.setOptions( (short) 0x000F );
-        spContainer1.setRecordId( EscherContainerRecord.SP_CONTAINER );
-        spContainer1.setOptions( (short) 0x000F );
-        spgr.setRecordId( EscherSpgrRecord.RECORD_ID );
-        spgr.setOptions( (short) 0x0001 );    // version
-        spgr.setRectX1( patriarch.getX1() );
-        spgr.setRectY1( patriarch.getY1() );
-        spgr.setRectX2( patriarch.getX2() );
-        spgr.setRectY2( patriarch.getY2() );
-        sp1.setRecordId( EscherSpRecord.RECORD_ID );
-        sp1.setOptions( (short) 0x0002 );
-        sp1.setShapeId( drawingManager.allocateShapeId(dg.getDrawingGroupId()) );
-        sp1.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH );
-
-        dgContainer.addChildRecord( dg );
-        dgContainer.addChildRecord( spgrContainer );
-        spgrContainer.addChildRecord( spContainer1 );
-        spContainer1.addChildRecord( spgr );
-        spContainer1.addChildRecord( sp1 );
-
-        addEscherRecord( dgContainer );
-    }
-
-    /** Retrieve the number of shapes (including the patriarch). */
-//    private int getNumberOfShapes( HSSFPatriarch patriarch )
-//    {
-//        return patriarch.countOfAllChildren();
-//    }
-
-    private static short sid( List records, int loc )
-    {
-        return ( (Record) records.get( loc ) ).getSid();
-    }
+	public static final short ST_MIN = (short) 0;
+	public static final short ST_NOT_PRIMATIVE = ST_MIN;
+	public static final short ST_RECTANGLE = (short) 1;
+	public static final short ST_ROUNDRECTANGLE = (short) 2;
+	public static final short ST_ELLIPSE = (short) 3;
+	public static final short ST_DIAMOND = (short) 4;
+	public static final short ST_ISOCELESTRIANGLE = (short) 5;
+	public static final short ST_RIGHTTRIANGLE = (short) 6;
+	public static final short ST_PARALLELOGRAM = (short) 7;
+	public static final short ST_TRAPEZOID = (short) 8;
+	public static final short ST_HEXAGON = (short) 9;
+	public static final short ST_OCTAGON = (short) 10;
+	public static final short ST_PLUS = (short) 11;
+	public static final short ST_STAR = (short) 12;
+	public static final short ST_ARROW = (short) 13;
+	public static final short ST_THICKARROW = (short) 14;
+	public static final short ST_HOMEPLATE = (short) 15;
+	public static final short ST_CUBE = (short) 16;
+	public static final short ST_BALLOON = (short) 17;
+	public static final short ST_SEAL = (short) 18;
+	public static final short ST_ARC = (short) 19;
+	public static final short ST_LINE = (short) 20;
+	public static final short ST_PLAQUE = (short) 21;
+	public static final short ST_CAN = (short) 22;
+	public static final short ST_DONUT = (short) 23;
+	public static final short ST_TEXTSIMPLE = (short) 24;
+	public static final short ST_TEXTOCTAGON = (short) 25;
+	public static final short ST_TEXTHEXAGON = (short) 26;
+	public static final short ST_TEXTCURVE = (short) 27;
+	public static final short ST_TEXTWAVE = (short) 28;
+	public static final short ST_TEXTRING = (short) 29;
+	public static final short ST_TEXTONCURVE = (short) 30;
+	public static final short ST_TEXTONRING = (short) 31;
+	public static final short ST_STRAIGHTCONNECTOR1 = (short) 32;
+	public static final short ST_BENTCONNECTOR2 = (short) 33;
+	public static final short ST_BENTCONNECTOR3 = (short) 34;
+	public static final short ST_BENTCONNECTOR4 = (short) 35;
+	public static final short ST_BENTCONNECTOR5 = (short) 36;
+	public static final short ST_CURVEDCONNECTOR2 = (short) 37;
+	public static final short ST_CURVEDCONNECTOR3 = (short) 38;
+	public static final short ST_CURVEDCONNECTOR4 = (short) 39;
+	public static final short ST_CURVEDCONNECTOR5 = (short) 40;
+	public static final short ST_CALLOUT1 = (short) 41;
+	public static final short ST_CALLOUT2 = (short) 42;
+	public static final short ST_CALLOUT3 = (short) 43;
+	public static final short ST_ACCENTCALLOUT1 = (short) 44;
+	public static final short ST_ACCENTCALLOUT2 = (short) 45;
+	public static final short ST_ACCENTCALLOUT3 = (short) 46;
+	public static final short ST_BORDERCALLOUT1 = (short) 47;
+	public static final short ST_BORDERCALLOUT2 = (short) 48;
+	public static final short ST_BORDERCALLOUT3 = (short) 49;
+	public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50;
+	public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51;
+	public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52;
+	public static final short ST_RIBBON = (short) 53;
+	public static final short ST_RIBBON2 = (short) 54;
+	public static final short ST_CHEVRON = (short) 55;
+	public static final short ST_PENTAGON = (short) 56;
+	public static final short ST_NOSMOKING = (short) 57;
+	public static final short ST_SEAL8 = (short) 58;
+	public static final short ST_SEAL16 = (short) 59;
+	public static final short ST_SEAL32 = (short) 60;
+	public static final short ST_WEDGERECTCALLOUT = (short) 61;
+	public static final short ST_WEDGERRECTCALLOUT = (short) 62;
+	public static final short ST_WEDGEELLIPSECALLOUT = (short) 63;
+	public static final short ST_WAVE = (short) 64;
+	public static final short ST_FOLDEDCORNER = (short) 65;
+	public static final short ST_LEFTARROW = (short) 66;
+	public static final short ST_DOWNARROW = (short) 67;
+	public static final short ST_UPARROW = (short) 68;
+	public static final short ST_LEFTRIGHTARROW = (short) 69;
+	public static final short ST_UPDOWNARROW = (short) 70;
+	public static final short ST_IRREGULARSEAL1 = (short) 71;
+	public static final short ST_IRREGULARSEAL2 = (short) 72;
+	public static final short ST_LIGHTNINGBOLT = (short) 73;
+	public static final short ST_HEART = (short) 74;
+	public static final short ST_PICTUREFRAME = (short) 75;
+	public static final short ST_QUADARROW = (short) 76;
+	public static final short ST_LEFTARROWCALLOUT = (short) 77;
+	public static final short ST_RIGHTARROWCALLOUT = (short) 78;
+	public static final short ST_UPARROWCALLOUT = (short) 79;
+	public static final short ST_DOWNARROWCALLOUT = (short) 80;
+	public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81;
+	public static final short ST_UPDOWNARROWCALLOUT = (short) 82;
+	public static final short ST_QUADARROWCALLOUT = (short) 83;
+	public static final short ST_BEVEL = (short) 84;
+	public static final short ST_LEFTBRACKET = (short) 85;
+	public static final short ST_RIGHTBRACKET = (short) 86;
+	public static final short ST_LEFTBRACE = (short) 87;
+	public static final short ST_RIGHTBRACE = (short) 88;
+	public static final short ST_LEFTUPARROW = (short) 89;
+	public static final short ST_BENTUPARROW = (short) 90;
+	public static final short ST_BENTARROW = (short) 91;
+	public static final short ST_SEAL24 = (short) 92;
+	public static final short ST_STRIPEDRIGHTARROW = (short) 93;
+	public static final short ST_NOTCHEDRIGHTARROW = (short) 94;
+	public static final short ST_BLOCKARC = (short) 95;
+	public static final short ST_SMILEYFACE = (short) 96;
+	public static final short ST_VERTICALSCROLL = (short) 97;
+	public static final short ST_HORIZONTALSCROLL = (short) 98;
+	public static final short ST_CIRCULARARROW = (short) 99;
+	public static final short ST_NOTCHEDCIRCULARARROW = (short) 100;
+	public static final short ST_UTURNARROW = (short) 101;
+	public static final short ST_CURVEDRIGHTARROW = (short) 102;
+	public static final short ST_CURVEDLEFTARROW = (short) 103;
+	public static final short ST_CURVEDUPARROW = (short) 104;
+	public static final short ST_CURVEDDOWNARROW = (short) 105;
+	public static final short ST_CLOUDCALLOUT = (short) 106;
+	public static final short ST_ELLIPSERIBBON = (short) 107;
+	public static final short ST_ELLIPSERIBBON2 = (short) 108;
+	public static final short ST_FLOWCHARTPROCESS = (short) 109;
+	public static final short ST_FLOWCHARTDECISION = (short) 110;
+	public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111;
+	public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112;
+	public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113;
+	public static final short ST_FLOWCHARTDOCUMENT = (short) 114;
+	public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115;
+	public static final short ST_FLOWCHARTTERMINATOR = (short) 116;
+	public static final short ST_FLOWCHARTPREPARATION = (short) 117;
+	public static final short ST_FLOWCHARTMANUALINPUT = (short) 118;
+	public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119;
+	public static final short ST_FLOWCHARTCONNECTOR = (short) 120;
+	public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121;
+	public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122;
+	public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123;
+	public static final short ST_FLOWCHARTOR = (short) 124;
+	public static final short ST_FLOWCHARTCOLLATE = (short) 125;
+	public static final short ST_FLOWCHARTSORT = (short) 126;
+	public static final short ST_FLOWCHARTEXTRACT = (short) 127;
+	public static final short ST_FLOWCHARTMERGE = (short) 128;
+	public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129;
+	public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130;
+	public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131;
+	public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132;
+	public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133;
+	public static final short ST_FLOWCHARTDISPLAY = (short) 134;
+	public static final short ST_FLOWCHARTDELAY = (short) 135;
+	public static final short ST_TEXTPLAINTEXT = (short) 136;
+	public static final short ST_TEXTSTOP = (short) 137;
+	public static final short ST_TEXTTRIANGLE = (short) 138;
+	public static final short ST_TEXTTRIANGLEINVERTED = (short) 139;
+	public static final short ST_TEXTCHEVRON = (short) 140;
+	public static final short ST_TEXTCHEVRONINVERTED = (short) 141;
+	public static final short ST_TEXTRINGINSIDE = (short) 142;
+	public static final short ST_TEXTRINGOUTSIDE = (short) 143;
+	public static final short ST_TEXTARCHUPCURVE = (short) 144;
+	public static final short ST_TEXTARCHDOWNCURVE = (short) 145;
+	public static final short ST_TEXTCIRCLECURVE = (short) 146;
+	public static final short ST_TEXTBUTTONCURVE = (short) 147;
+	public static final short ST_TEXTARCHUPPOUR = (short) 148;
+	public static final short ST_TEXTARCHDOWNPOUR = (short) 149;
+	public static final short ST_TEXTCIRCLEPOUR = (short) 150;
+	public static final short ST_TEXTBUTTONPOUR = (short) 151;
+	public static final short ST_TEXTCURVEUP = (short) 152;
+	public static final short ST_TEXTCURVEDOWN = (short) 153;
+	public static final short ST_TEXTCASCADEUP = (short) 154;
+	public static final short ST_TEXTCASCADEDOWN = (short) 155;
+	public static final short ST_TEXTWAVE1 = (short) 156;
+	public static final short ST_TEXTWAVE2 = (short) 157;
+	public static final short ST_TEXTWAVE3 = (short) 158;
+	public static final short ST_TEXTWAVE4 = (short) 159;
+	public static final short ST_TEXTINFLATE = (short) 160;
+	public static final short ST_TEXTDEFLATE = (short) 161;
+	public static final short ST_TEXTINFLATEBOTTOM = (short) 162;
+	public static final short ST_TEXTDEFLATEBOTTOM = (short) 163;
+	public static final short ST_TEXTINFLATETOP = (short) 164;
+	public static final short ST_TEXTDEFLATETOP = (short) 165;
+	public static final short ST_TEXTDEFLATEINFLATE = (short) 166;
+	public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167;
+	public static final short ST_TEXTFADERIGHT = (short) 168;
+	public static final short ST_TEXTFADELEFT = (short) 169;
+	public static final short ST_TEXTFADEUP = (short) 170;
+	public static final short ST_TEXTFADEDOWN = (short) 171;
+	public static final short ST_TEXTSLANTUP = (short) 172;
+	public static final short ST_TEXTSLANTDOWN = (short) 173;
+	public static final short ST_TEXTCANUP = (short) 174;
+	public static final short ST_TEXTCANDOWN = (short) 175;
+	public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176;
+	public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177;
+	public static final short ST_CALLOUT90 = (short) 178;
+	public static final short ST_ACCENTCALLOUT90 = (short) 179;
+	public static final short ST_BORDERCALLOUT90 = (short) 180;
+	public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181;
+	public static final short ST_LEFTRIGHTUPARROW = (short) 182;
+	public static final short ST_SUN = (short) 183;
+	public static final short ST_MOON = (short) 184;
+	public static final short ST_BRACKETPAIR = (short) 185;
+	public static final short ST_BRACEPAIR = (short) 186;
+	public static final short ST_SEAL4 = (short) 187;
+	public static final short ST_DOUBLEWAVE = (short) 188;
+	public static final short ST_ACTIONBUTTONBLANK = (short) 189;
+	public static final short ST_ACTIONBUTTONHOME = (short) 190;
+	public static final short ST_ACTIONBUTTONHELP = (short) 191;
+	public static final short ST_ACTIONBUTTONINFORMATION = (short) 192;
+	public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193;
+	public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194;
+	public static final short ST_ACTIONBUTTONEND = (short) 195;
+	public static final short ST_ACTIONBUTTONBEGINNING = (short) 196;
+	public static final short ST_ACTIONBUTTONRETURN = (short) 197;
+	public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198;
+	public static final short ST_ACTIONBUTTONSOUND = (short) 199;
+	public static final short ST_ACTIONBUTTONMOVIE = (short) 200;
+	public static final short ST_HOSTCONTROL = (short) 201;
+	public static final short ST_TEXTBOX = (short) 202;
+	public static final short ST_NIL = (short) 0x0FFF;
+
+	protected HSSFPatriarch patriarch;
+
+	/** Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord} */
+	private Map<EscherRecord, Record> shapeToObj = new HashMap<EscherRecord, Record>();
+	private DrawingManager2 drawingManager;
+	private short drawingGroupId;
+
+	/**
+	 * list of "tail" records that need to be serialized after all drawing group records
+	 */
+	private List tailRec = new ArrayList();
+
+	public EscherAggregate( DrawingManager2 drawingManager )
+	{
+		this.drawingManager = drawingManager;
+	}
+
+	/**
+	 * @return  Returns the current sid.
+	 */
+	public short getSid()
+	{
+		return sid;
+	}
+
+	/**
+	 * Calculates the string representation of this record.  This is
+	 * simply a dump of all the records.
+	 */
+	public String toString()
+	{
+		String nl = System.getProperty( "line.separtor" );
+
+		StringBuffer result = new StringBuffer();
+		result.append( '[' ).append( getRecordName() ).append( ']' + nl );
+		for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); )
+		{
+			EscherRecord escherRecord = (EscherRecord) iterator.next();
+			result.append( escherRecord.toString() );
+		}
+		result.append( "[/" ).append( getRecordName() ).append( ']' + nl );
+
+		return result.toString();
+	}
+
+	/**
+	 * Collapses the drawing records into an aggregate.
+	 */
+	public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager2 drawingManager )
+	{
+		// Keep track of any shape records created so we can match them back to the object id's.
+		// Textbox objects are also treated as shape objects.
+		final List<EscherRecord> shapeRecords = new ArrayList<EscherRecord>();
+		EscherRecordFactory recordFactory = new DefaultEscherRecordFactory()
+		{
+			public EscherRecord createRecord( byte[] data, int offset )
+			{
+				EscherRecord r = super.createRecord( data, offset );
+				if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID )
+				{
+					shapeRecords.add( r );
+				}
+				return r;
+			}
+		};
+
+		// Calculate the size of the buffer
+		EscherAggregate agg = new EscherAggregate(drawingManager);
+		int loc = locFirstDrawingRecord;
+		int dataSize = 0;
+		while ( loc + 1 < records.size()
+				&& sid( records, loc ) == DrawingRecord.sid
+				&& isObjectRecord( records, loc + 1 ) )
+		{
+			dataSize += ( (DrawingRecord) records.get( loc ) ).getData().length;
+			loc += 2;
+		}
+
+		// Create one big buffer
+		byte buffer[] = new byte[dataSize];
+		int offset = 0;
+		loc = locFirstDrawingRecord;
+		while ( loc + 1 < records.size()
+				&& sid( records, loc ) == DrawingRecord.sid
+				&& isObjectRecord( records, loc + 1 ) )
+		{
+			DrawingRecord drawingRecord = (DrawingRecord) records.get( loc );
+			System.arraycopy( drawingRecord.getData(), 0, buffer, offset, drawingRecord.getData().length );
+			offset += drawingRecord.getData().length;
+			loc += 2;
+		}
+
+		// Decode the shapes
+		//		agg.escherRecords = new ArrayList();
+		int pos = 0;
+		while ( pos < dataSize )
+		{
+			EscherRecord r = recordFactory.createRecord( buffer, pos );
+			int bytesRead = r.fillFields( buffer, pos, recordFactory );
+			agg.addEscherRecord( r );
+			pos += bytesRead;
+		}
+
+		// Associate the object records with the shapes
+		loc = locFirstDrawingRecord;
+		int shapeIndex = 0;
+		agg.shapeToObj = new HashMap<EscherRecord, Record>();
+		while ( loc + 1 < records.size()
+				&& sid( records, loc ) == DrawingRecord.sid
+				&& isObjectRecord( records, loc + 1 ) )
+		{
+			Record objRecord = (Record) records.get( loc + 1 );
+			agg.shapeToObj.put( shapeRecords.get( shapeIndex++ ), objRecord );
+			loc += 2;
+		}
+
+		return agg;
+
+	}
+
+	/**
+	 * Serializes this aggregate to a byte array.  Since this is an aggregate
+	 * record it will effectively serialize the aggregated records.
+	 *
+	 * @param offset	The offset into the start of the array.
+	 * @param data	  The byte array to serialize to.
+	 * @return		  The number of bytes serialized.
+	 */
+	public int serialize( int offset, byte[] data )
+	{
+		convertUserModelToRecords();
+
+		// Determine buffer size
+		List records = getEscherRecords();
+		int size = getEscherRecordSize( records );
+		byte[] buffer = new byte[size];
+
+
+		// Serialize escher records into one big data structure and keep note of ending offsets.
+		final List spEndingOffsets = new ArrayList();
+		final List shapes = new ArrayList();
+		int pos = 0;
+		for ( Iterator iterator = records.iterator(); iterator.hasNext(); )
+		{
+			EscherRecord e = (EscherRecord) iterator.next();
+			pos += e.serialize( pos, buffer, new EscherSerializationListener()
+			{
+				public void beforeRecordSerialize( int offset, short recordId, EscherRecord record )
+				{
+				}
+
+				public void afterRecordSerialize( int offset, short recordId, int size, EscherRecord record )
+				{
+					if ( recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID )
+					{
+						spEndingOffsets.add( new Integer( offset ) );
+						shapes.add( record );
+					}
+				}
+			} );
+		}
+		// todo: fix this
+		shapes.add( 0, null );
+		spEndingOffsets.add( 0, null );
+
+		// Split escher records into separate MSODRAWING and OBJ, TXO records.  (We don't break on
+		// the first one because it's the patriach).
+		pos = offset;
+		for ( int i = 1; i < shapes.size(); i++ )
+		{
+			int endOffset = ( (Integer) spEndingOffsets.get( i ) ).intValue() - 1;
+			int startOffset;
+			if ( i == 1 )
+				startOffset = 0;
+			else
+				startOffset = ( (Integer) spEndingOffsets.get( i - 1 ) ).intValue();
+
+			// Create and write a new MSODRAWING record
+			DrawingRecord drawing = new DrawingRecord();
+			byte[] drawingData = new byte[endOffset - startOffset + 1];
+			System.arraycopy( buffer, startOffset, drawingData, 0, drawingData.length );
+			drawing.setData( drawingData );
+			int temp = drawing.serialize( pos, data );
+			pos += temp;
+
+			// Write the matching OBJ record
+			Record obj = (Record) shapeToObj.get( shapes.get( i ) );
+			temp = obj.serialize( pos, data );
+			pos += temp;
+
+		}
+
+		// write records that need to be serialized after all drawing group records
+		for ( int i = 0; i < tailRec.size(); i++ )
+		{
+			Record rec = (Record)tailRec.get(i);
+			pos += rec.serialize( pos, data );
+		}
+
+		int bytesWritten = pos - offset;
+		if ( bytesWritten != getRecordSize() )
+			throw new RecordFormatException( bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize() );
+		return bytesWritten;
+	}
+
+	/**
+	 * How many bytes do the raw escher records contain.
+	 * @param records   List of escher records
+	 * @return  the number of bytes
+	 */
+	private int getEscherRecordSize( List records )
+	{
+		int size = 0;
+		for ( Iterator iterator = records.iterator(); iterator.hasNext(); )
+			size += ( (EscherRecord) iterator.next() ).getRecordSize();
+		return size;
+	}
+
+	public int getRecordSize() {
+		// TODO - convert this to RecordAggregate
+		convertUserModelToRecords();
+		List records = getEscherRecords();
+		int rawEscherSize = getEscherRecordSize( records );
+		int drawingRecordSize = rawEscherSize + ( shapeToObj.size() ) * 4;
+		int objRecordSize = 0;
+		for ( Iterator iterator = shapeToObj.values().iterator(); iterator.hasNext(); )
+		{
+			Record r = (Record) iterator.next();
+			objRecordSize += r.getRecordSize();
+		}
+		int tailRecordSize = 0;
+		for ( Iterator iterator = tailRec.iterator(); iterator.hasNext(); )
+		{
+			Record r = (Record) iterator.next();
+			tailRecordSize += r.getRecordSize();
+		}
+		return drawingRecordSize + objRecordSize + tailRecordSize;
+	}
+
+	/**
+	 * Associates an escher record to an OBJ record or a TXO record.
+	 */
+	Object associateShapeToObjRecord( EscherRecord r, ObjRecord objRecord )
+	{
+		return shapeToObj.put( r, objRecord );
+	}
+
+	public HSSFPatriarch getPatriarch()
+	{
+		return patriarch;
+	}
+
+	public void setPatriarch( HSSFPatriarch patriarch )
+	{
+		this.patriarch = patriarch;
+	}
+	
+	/**
+	 * Converts the Records into UserModel
+	 *  objects on the bound HSSFPatriarch
+	 */
+	public void convertRecordsToUserModel() {
+		if(patriarch == null) {
+			throw new IllegalStateException("Must call setPatriarch() first");
+		}
+		
+		// The top level container ought to have
+		//  the DgRecord and the container of one container
+		//  per shape group (patriach overall first)
+		EscherContainerRecord topContainer = getEscherContainer();
+		if(topContainer == null) {
+			return;
+		}
+		topContainer = (EscherContainerRecord) 
+			topContainer.getChildContainers().get(0);
+		
+		List tcc = topContainer.getChildContainers();
+		if(tcc.size() == 0) {
+			throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!");
+		}
+		
+		// First up, get the patriach position
+		// This is in the first EscherSpgrRecord, in
+		//  the first container, with a EscherSRecord too
+		EscherContainerRecord patriachContainer =
+			(EscherContainerRecord)tcc.get(0);
+		EscherSpgrRecord spgr = null;
+		for(Iterator<EscherRecord> it = patriachContainer.getChildIterator(); it.hasNext();) {
+			EscherRecord r = it.next();
+			if(r instanceof EscherSpgrRecord) {
+				spgr = (EscherSpgrRecord)r;
+				break;
+			}
+		}
+		if(spgr != null) {
+			patriarch.setCoordinates(
+					spgr.getRectX1(), spgr.getRectY1(),
+					spgr.getRectX2(), spgr.getRectY2()
+			);
+		}
+		
+		// Now process the containers for each group
+		//  and objects
+		for(int i=1; i<tcc.size(); i++) {
+			EscherContainerRecord shapeContainer =
+				(EscherContainerRecord)tcc.get(i);
+			//System.err.println("\n\n*****\n\n");
+			//System.err.println(shapeContainer);
+			
+			// Could be a group, or a base object
+			if(shapeContainer.getChildRecords().size() == 1 &&
+					shapeContainer.getChildContainers().size() == 1) {
+				// Group
+				HSSFShapeGroup group =
+					new HSSFShapeGroup(null, new HSSFClientAnchor());
+				patriarch.getChildren().add(group);
+				
+				EscherContainerRecord groupContainer =
+					(EscherContainerRecord)shapeContainer.getChild(0);
+				convertRecordsToUserModel(groupContainer, group);
+			} else if(shapeContainer.hasChildOfType((short)0xF00D)) {
+				// TextBox
+				HSSFTextbox box =
+					new HSSFTextbox(null, new HSSFClientAnchor());
+				patriarch.getChildren().add(box);
+				
+				convertRecordsToUserModel(shapeContainer, box);
+			} else if(shapeContainer.hasChildOfType((short)0xF011)) {
+				// Not yet supporting EscherClientDataRecord stuff
+			} else {
+				// Base level
+				convertRecordsToUserModel(shapeContainer, patriarch);
+			}
+		}
+		
+		// Now, clear any trace of what records make up
+		//  the patriarch
+		// Otherwise, everything will go horribly wrong
+		//  when we try to write out again....
+//		clearEscherRecords();
+		drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]);
+
+		// TODO: Support converting our records
+		//  back into shapes
+		log.log(POILogger.WARN, "Not processing objects into Patriarch!");
+	}
+	
+	private void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) {
+		for(Iterator<EscherRecord> it = shapeContainer.getChildIterator(); it.hasNext();) {
+			EscherRecord r = it.next();
+			if(r instanceof EscherSpgrRecord) {
+				// This may be overriden by a later EscherClientAnchorRecord
+				EscherSpgrRecord spgr = (EscherSpgrRecord)r;
+				
+				if(model instanceof HSSFShapeGroup) {
+					HSSFShapeGroup g = (HSSFShapeGroup)model;
+					g.setCoordinates(
+							spgr.getRectX1(), spgr.getRectY1(),
+							spgr.getRectX2(), spgr.getRectY2()
+					);
+				} else {
+					throw new IllegalStateException("Got top level anchor but not processing a group");
+				}
+			} 
+			else if(r instanceof EscherClientAnchorRecord) {
+				EscherClientAnchorRecord car = (EscherClientAnchorRecord)r;
+				
+				if(model instanceof HSSFShape) {
+					HSSFShape g = (HSSFShape)model;
+					g.getAnchor().setDx1(car.getDx1());
+					g.getAnchor().setDx2(car.getDx2());
+					g.getAnchor().setDy1(car.getDy1());
+					g.getAnchor().setDy2(car.getDy2());
+				} else {
+					throw new IllegalStateException("Got top level anchor but not processing a group or shape");
+				}
+			}
+			else if(r instanceof EscherTextboxRecord) {
+				EscherTextboxRecord tbr = (EscherTextboxRecord)r;
+				
+				// Also need to find the TextObjectRecord too
+				// TODO
+			}
+			else if(r instanceof EscherSpRecord) {
+				// Use flags if needed
+			}
+			else if(r instanceof EscherOptRecord) {
+				// Use properties if needed
+			}
+			else {
+				//System.err.println(r);
+			}
+		}
+	}
+	
+	public void clear()
+	{
+		clearEscherRecords();
+		shapeToObj.clear();
+//		lastShapeId = 1024;
+	}
+
+	protected String getRecordName()
+	{
+		return "ESCHERAGGREGATE";
+	}
+
+	// =============== Private methods ========================
+
+	private static boolean isObjectRecord( List records, int loc )
+	{
+		return sid( records, loc ) == ObjRecord.sid || sid( records, loc ) == TextObjectRecord.sid;
+	}
+
+	private void convertUserModelToRecords()
+	{
+		if ( patriarch != null )
+		{
+			shapeToObj.clear();
+			tailRec.clear();
+			clearEscherRecords();
+			if ( patriarch.getChildren().size() != 0 )
+			{
+				convertPatriarch( patriarch );
+				EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord( 0 );
+				EscherContainerRecord spgrContainer = null;
+				Iterator<EscherRecord> iter = dgContainer.getChildIterator();
+				while (iter.hasNext()) {
+					EscherRecord child = iter.next();
+					if (child.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
+						spgrContainer = (EscherContainerRecord) child;
+					}
+				}
+				convertShapes( patriarch, spgrContainer, shapeToObj );
+
+				patriarch = null;
+			}
+		}
+	}
+
+	private void convertShapes( HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj )
+	{
+		if ( escherParent == null ) throw new IllegalArgumentException( "Parent record required" );
+
+		List shapes = parent.getChildren();
+		for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
+		{
+			HSSFShape shape = (HSSFShape) iterator.next();
+			if ( shape instanceof HSSFShapeGroup )
+			{
+				convertGroup( (HSSFShapeGroup) shape, escherParent, shapeToObj );
+			}
+			else
+			{
+				AbstractShape shapeModel = AbstractShape.createShape(
+						shape,
+						drawingManager.allocateShapeId(drawingGroupId) );
+				shapeToObj.put( findClientData( shapeModel.getSpContainer() ), shapeModel.getObjRecord() );
+				if ( shapeModel instanceof TextboxShape )
+				{
+					EscherRecord escherTextbox = ( (TextboxShape) shapeModel ).getEscherTextbox();
+					shapeToObj.put( escherTextbox, ( (TextboxShape) shapeModel ).getTextObjectRecord() );
+					//					escherParent.addChildRecord(escherTextbox);
+					
+					if ( shapeModel instanceof CommentShape ){
+						CommentShape comment = (CommentShape)shapeModel;
+						tailRec.add(comment.getNoteRecord());
+					}
+
+				}
+				escherParent.addChildRecord( shapeModel.getSpContainer() );
+			}
+		}
+//		drawingManager.newCluster( (short)1 );
+//		drawingManager.newCluster( (short)2 );
+
+	}
+
+	private void convertGroup( HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj )
+	{
+		EscherContainerRecord spgrContainer = new EscherContainerRecord();
+		EscherContainerRecord spContainer = new EscherContainerRecord();
+		EscherSpgrRecord spgr = new EscherSpgrRecord();
+		EscherSpRecord sp = new EscherSpRecord();
+		EscherOptRecord opt = new EscherOptRecord();
+		EscherRecord anchor;
+		EscherClientDataRecord clientData = new EscherClientDataRecord();
+
+		spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER );
+		spgrContainer.setOptions( (short) 0x000F );
+		spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
+		spContainer.setOptions( (short) 0x000F );
+		spgr.setRecordId( EscherSpgrRecord.RECORD_ID );
+		spgr.setOptions( (short) 0x0001 );
+		spgr.setRectX1( shape.getX1() );
+		spgr.setRectY1( shape.getY1() );
+		spgr.setRectX2( shape.getX2() );
+		spgr.setRectY2( shape.getY2() );
+		sp.setRecordId( EscherSpRecord.RECORD_ID );
+		sp.setOptions( (short) 0x0002 );
+		int shapeId = drawingManager.allocateShapeId(drawingGroupId);
+		sp.setShapeId( shapeId );
+		if (shape.getAnchor() instanceof HSSFClientAnchor)
+			sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR );
+		else
+			sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD );
+		opt.setRecordId( EscherOptRecord.RECORD_ID );
+		opt.setOptions( (short) 0x0023 );
+		opt.addEscherProperty( new EscherBoolProperty( EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004 ) );
+		opt.addEscherProperty( new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x00080000 ) );
+
+		anchor = ConvertAnchor.createAnchor( shape.getAnchor() );
+//		clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() );
+//		clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() );
+//		clientAnchor.setDx1( (short) shape.getAnchor().getDx1() );
+//		clientAnchor.setDy1( (short) shape.getAnchor().getDy1() );
+//		clientAnchor.setCol2( ( (HSSFClientAnchor) shape.getAnchor() ).getCol2() );
+//		clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() );
+//		clientAnchor.setDx2( (short) shape.getAnchor().getDx2() );
+//		clientAnchor.setDy2( (short) shape.getAnchor().getDy2() );
+		clientData.setRecordId( EscherClientDataRecord.RECORD_ID );
+		clientData.setOptions( (short) 0x0000 );
+
+		spgrContainer.addChildRecord( spContainer );
+		spContainer.addChildRecord( spgr );
+		spContainer.addChildRecord( sp );
+		spContainer.addChildRecord( opt );
+		spContainer.addChildRecord( anchor );
+		spContainer.addChildRecord( clientData );
+
+		ObjRecord obj = new ObjRecord();
+		CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
+		cmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_GROUP );
+		cmo.setObjectId( (short) ( shapeId ) );
+		cmo.setLocked( true );
+		cmo.setPrintable( true );
+		cmo.setAutofill( true );
+		cmo.setAutoline( true );
+		GroupMarkerSubRecord gmo = new GroupMarkerSubRecord();
+		EndSubRecord end = new EndSubRecord();
+		obj.addSubRecord( cmo );
+		obj.addSubRecord( gmo );
+		obj.addSubRecord( end );
+		shapeToObj.put( clientData, obj );
+
+		escherParent.addChildRecord( spgrContainer );
+
+		convertShapes( shape, spgrContainer, shapeToObj );
+
+	}
+
+	private EscherRecord findClientData( EscherContainerRecord spContainer )
+	{
+		for (Iterator<EscherRecord> iterator = spContainer.getChildIterator(); iterator.hasNext();) {
+			EscherRecord r = iterator.next();
+			if (r.getRecordId() == EscherClientDataRecord.RECORD_ID) {
+				return r;
+			}
+		}
+		throw new IllegalArgumentException( "Can not find client data record" );
+	}
+
+	private void convertPatriarch( HSSFPatriarch patriarch )
+	{
+		EscherContainerRecord dgContainer = new EscherContainerRecord();
+		EscherDgRecord dg;
+		EscherContainerRecord spgrContainer = new EscherContainerRecord();
+		EscherContainerRecord spContainer1 = new EscherContainerRecord();
+		EscherSpgrRecord spgr = new EscherSpgrRecord();
+		EscherSpRecord sp1 = new EscherSpRecord();
+
+		dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER );
+		dgContainer.setOptions( (short) 0x000F );
+		dg = drawingManager.createDgRecord();
+		drawingGroupId = dg.getDrawingGroupId();
+//		dg.setOptions( (short) ( drawingId << 4 ) );
+//		dg.setNumShapes( getNumberOfShapes( patriarch ) );
+//		dg.setLastMSOSPID( 0 );  // populated after all shape id's are assigned.
+		spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER );
+		spgrContainer.setOptions( (short) 0x000F );
+		spContainer1.setRecordId( EscherContainerRecord.SP_CONTAINER );
+		spContainer1.setOptions( (short) 0x000F );
+		spgr.setRecordId( EscherSpgrRecord.RECORD_ID );
+		spgr.setOptions( (short) 0x0001 );	// version
+		spgr.setRectX1( patriarch.getX1() );
+		spgr.setRectY1( patriarch.getY1() );
+		spgr.setRectX2( patriarch.getX2() );
+		spgr.setRectY2( patriarch.getY2() );
+		sp1.setRecordId( EscherSpRecord.RECORD_ID );
+		sp1.setOptions( (short) 0x0002 );
+		sp1.setShapeId( drawingManager.allocateShapeId(dg.getDrawingGroupId()) );
+		sp1.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH );
+
+		dgContainer.addChildRecord( dg );
+		dgContainer.addChildRecord( spgrContainer );
+		spgrContainer.addChildRecord( spContainer1 );
+		spContainer1.addChildRecord( spgr );
+		spContainer1.addChildRecord( sp1 );
+
+		addEscherRecord( dgContainer );
+	}
+
+
+	private static short sid( List records, int loc )
+	{
+		return ( (Record) records.get( loc ) ).getSid();
+	}
 
 
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowRecordDumper.java Fri Feb 20 01:55:47 2009
@@ -201,22 +201,20 @@
         String nl = System.getProperty( "line.separator" );
 
         StringBuffer children = new StringBuffer();
-        if ( ecr.getChildRecords().size() > 0 )
+        int count = 0;
+        for ( Iterator<EscherRecord> iterator = ecr.getChildIterator(); iterator.hasNext(); )
         {
-            children.append( "  children: " + nl );
+            if (count < 1) {
+                children.append( "  children: " + nl );
+            }
+            String newIndent = "   ";
+
+            EscherRecord record = iterator.next();
+            children.append(newIndent + "Child " + count + ":" + nl);
             
-            int count = 0;
-            for ( Iterator iterator = ecr.getChildRecords().iterator(); iterator.hasNext(); )
-            {
-            	String newIndent = "   ";
-            	
-                EscherRecord record = (EscherRecord) iterator.next();
-                children.append(newIndent + "Child " + count + ":" + nl);
-                
-               	children.append( printEscherRecord(record) );
+           	children.append( printEscherRecord(record) );
 
-                count++;
-            }
+            count++;
         }
 
         return 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java Fri Feb 20 01:55:47 2009
@@ -76,7 +76,7 @@
 
         EscherClientDataRecord cldata = new EscherClientDataRecord();
         cldata.setOptions((short)0xF);
-        _escherContainer.getChildRecords().add(cldata);
+        _escherContainer.addChildRecord(cldata); // TODO unit test to prove getChildRecords().add is wrong
 
         OEShapeAtom oe = new OEShapeAtom();
 
@@ -100,7 +100,7 @@
      */
     public void setActiveXIndex(int idx){
         EscherContainerRecord spContainer = getSpContainer();
-        for (Iterator<EscherRecord> it = spContainer.getChildRecords().iterator(); it.hasNext();) {
+        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
             EscherRecord obj = it.next();
             if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
                 EscherClientDataRecord clientRecord = (EscherClientDataRecord)obj;

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java Fri Feb 20 01:55:47 2009
@@ -177,11 +177,10 @@
         }
 
         EscherContainerRecord spContainer = shape.getSpContainer();
-        List spchild = spContainer.getChildRecords();
-        for (Iterator it = spchild.iterator(); it.hasNext(); ) {
-            EscherRecord obj = (EscherRecord)it.next();
+        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext(); ) {
+            EscherRecord obj = it.next();
             if (obj.getRecordId() ==  EscherClientDataRecord.RECORD_ID){
-                byte[] data = ((EscherContainerRecord)obj).serialize();
+                byte[] data = obj.serialize();
                 Record[] records = Record.findChildRecords(data, 8, data.length-8);
                 if(records != null) find(records, exobj, lst);
             }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java Fri Feb 20 01:55:47 2009
@@ -86,13 +86,7 @@
         cldata.setRemainingData(out.toByteArray());
 
         //append placeholder container before EscherTextboxRecord
-        List lst = _escherContainer.getChildRecords();
-        for (int i = 0; i < lst.size(); i++) {
-              EscherRecord rec = (EscherRecord)lst.get(i);
-              if(rec.getRecordId() == EscherTextboxRecord.RECORD_ID){
-                  lst.add(i++, cldata);
-              }
-        }
+        _escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
 
         return _escherContainer;
     }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java Fri Feb 20 01:55:47 2009
@@ -246,9 +246,9 @@
      * @return escher record or <code>null</code> if not found.
      */
     public static EscherRecord getEscherChild(EscherContainerRecord owner, int recordId){
-        for ( Iterator iterator = owner.getChildRecords().iterator(); iterator.hasNext(); )
+        for ( Iterator<EscherRecord> iterator = owner.getChildIterator(); iterator.hasNext(); )
         {
-            EscherRecord escherRecord = (EscherRecord) iterator.next();
+            EscherRecord escherRecord = iterator.next();
             if (escherRecord.getRecordId() == recordId)
                 return escherRecord;
         }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java?rev=746085&r1=746084&r2=746085&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java Fri Feb 20 01:55:47 2009
@@ -125,8 +125,8 @@
 
     protected static Record getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
         Record oep = null;
-        for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
-            EscherRecord obj = (EscherRecord) it.next();
+        for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
+            EscherRecord obj = it.next();
             if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
                 byte[] data = obj.serialize();
                 Record[] records = Record.findChildRecords(data, 8, data.length - 8);



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org